Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions sonar/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Package sonar is a Go client for the SonarQube web API.
//
// The root type is Client. Create one with NewClient and reach each API area
// through a typed service field, for example client.Projects, client.Issues or
// client.Qualitygates. V2 API services are grouped under client.V2.
//
// # Authentication
//
// SonarQube supports token authentication (recommended) and basic auth. Both
// can be supplied at construction via ClientCreateOptions or with the WithToken
// and WithBasicAuth options:
//
// client, err := sonar.NewClient(nil,
// sonar.WithBaseURL("https://sonarqube.example.com/api/"),
// sonar.WithToken("my-token"),
// )
//
// In CI/CD environments the SONAR_URL, SONAR_TOKEN, SONAR_USERNAME, and
// SONAR_PASSWORD environment variables can be used instead:
//
// client, err := sonar.NewClientFromEnv()
//
// # Requests and responses
//
// Every service method takes a context.Context and, where applicable, a typed
// *<Service><Method>Options struct whose fields are validated before the request
// is sent. Methods return the decoded response, the raw *http.Response, and an
// error.
//
// # V1 vs V2
//
// V1 endpoints encode parameters as URL query values (url:"" struct tags). V2
// endpoints use JSON tags, support a request body, and live under the V2 field;
// the "v2/" path prefix is added automatically.
//
// # Errors
//
// API errors are returned as *ResponseError. Use the sentinel helpers
// (IsNotFound, IsUnauthorized, IsForbidden, IsConflict, IsRateLimited,
// IsServerError) to branch on the HTTP status without unwrapping by hand.
//
// # Pagination
//
// Paginated V1 endpoints expose both a single-page method (Search) and a
// convenience method that fetches every page (SearchAll / ListAll).
//
// # Resilience
//
// Retries with exponential backoff and jitter are opt-in via WithRetry. The
// transport can be customized with WithTransportConfig, and arbitrary
// http.RoundTripper middleware (logging, tracing, metrics) can be attached with
// WithMiddleware.
package sonar
97 changes: 97 additions & 0 deletions sonar/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package sonar_test

import (
"context"
"fmt"
"time"

"github.com/boxboxjason/sonarqube-client-go/sonar"
)

// Create a client with token authentication and search for projects.
func Example() {
client, err := sonar.NewClient(nil,
sonar.WithBaseURL("https://sonarqube.example.com/api/"),
sonar.WithToken("my-token"),
)
if err != nil {
panic(err)
}

result, _, err := client.Projects.Search(context.Background(), &sonar.ProjectsSearchOptions{
Query: "my-service",
})
if err != nil {
panic(err)
}

for _, project := range result.Components {
fmt.Println(project.Key)
}
}

// Fetch every page of a paginated endpoint with the SearchAll helper.
func ExampleProjectsService_SearchAll() {
client, err := sonar.NewClient(nil,
sonar.WithBaseURL("https://sonarqube.example.com/api/"),
sonar.WithToken("my-token"),
)
if err != nil {
panic(err)
}

//nolint:exhaustruct // only the filter we care about is set
projects, _, err := client.Projects.SearchAll(context.Background(), &sonar.ProjectsSearchOptions{})
if err != nil {
panic(err)
}

fmt.Printf("found %d projects\n", len(projects))
}

// Enable retries with exponential backoff for transient server errors.
func ExampleWithRetry() {
client, err := sonar.NewClient(nil,
sonar.WithBaseURL("https://sonarqube.example.com/api/"),
sonar.WithToken("my-token"),
sonar.WithRetry(sonar.RetryOptions{
MaxAttempts: 3,
InitialDelay: 100 * time.Millisecond,
MaxDelay: 2 * time.Second,
RetryableStatusCodes: []int{502, 503, 504},
}),
)
if err != nil {
panic(err)
}

_ = client
// Output:
}

// Branch on the HTTP status of an API error using the sentinel helpers.
func ExampleIsNotFound() {
client, err := sonar.NewClient(nil,
sonar.WithBaseURL("https://sonarqube.example.com/api/"),
sonar.WithToken("my-token"),
)
if err != nil {
panic(err)
}

_, err = client.Projects.Delete(context.Background(), &sonar.ProjectsDeleteOptions{Project: "missing-project"})
if sonar.IsNotFound(err) {
fmt.Println("project not found")
}
}

// Configure a client from SONAR_URL and SONAR_TOKEN environment variables.
func ExampleNewClientFromEnv() {
client, err := sonar.NewClientFromEnv()
if err != nil {
panic(err)
}

_ = client
// Output:
}
Loading