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
22 changes: 20 additions & 2 deletions tools/foas/openapi/filter/code_sample.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
var goSDKTemplate string

const codeSampleExtensionName = "x-codeSamples"
const atlasCliExtensionName = "x-xgen-atlascli"

// https://redocly.com/docs-legacy/api-reference-docs/specification-extensions/x-code-samples#x-codesamples
type codeSample struct {
Expand Down Expand Up @@ -147,6 +148,19 @@ func apiVersion(version *apiversion.APIVersion) string {
return version.Date().Format(time.DateOnly) + ".upcoming"
}

// skipAtlasCliCodeSample reports whether the Atlas CLI code sample generation should be skipped
// for the given operation. It is skipped only when the "x-xgen-atlascli" extension is present and
// sets "skip" to true, since in that case atlascli owns the command generation.
func skipAtlasCliCodeSample(op *openapi3.Operation) bool {
atlasCli, ok := op.Extensions[atlasCliExtensionName].(map[string]any)
if !ok {
return false
}

skip, _ := atlasCli["skip"].(bool)
return skip
}

func newAtlasCliCodeSamplesForOperation(op *openapi3.Operation) codeSample {
tag := strcase.ToLowerCamel(op.Tags[0])
operationID := strcase.ToLowerCamel(op.OperationID)
Expand Down Expand Up @@ -215,8 +229,12 @@ func (f *CodeSampleFilter) includeCodeSamplesForOperation(pathName, opMethod str
op.Extensions = map[string]any{}
}

codeSamples := []codeSample{
newAtlasCliCodeSamplesForOperation(op),
// The Atlas CLI code sample is generated when the "x-xgen-atlascli" extension is missing
// or when it is present with "skip: false". When the extension sets "skip: true", atlascli
// owns the command generation and no Atlas CLI sample is emitted.
var codeSamples []codeSample
if !skipAtlasCliCodeSample(op) {
codeSamples = append(codeSamples, newAtlasCliCodeSamplesForOperation(op))
}
Comment thread
andreaangiolillo marked this conversation as resolved.

if f.metadata.targetVersion.IsStable() {
Expand Down
185 changes: 185 additions & 0 deletions tools/foas/openapi/filter/code_sample_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,191 @@ func TestCodeSampleFilter(t *testing.T) {
})),
},
},
{
name: "stable api with x-xgen-atlascli skip false emits the Atlas CLI code sample",
version: "2025-01-01",
oas: &openapi3.T{
Paths: openapi3.NewPaths(openapi3.WithPath("/test", &openapi3.PathItem{
Get: &openapi3.Operation{
OperationID: "testOperationID",
Summary: "testSummary",
Responses: openapi3.NewResponses(openapi3.WithName("200", &openapi3.Response{
Content: openapi3.Content{
"application/vnd.atlas.2025-01-01+json": {
Schema: &openapi3.SchemaRef{
Ref: "#/components/schemas/PaginatedAppUserView",
},
Extensions: map[string]any{
"x-gen-version": "2025-01-01",
},
},
},
})),
Tags: []string{"TestTag"},
Extensions: map[string]any{
"x-sunset": "9999-12-31",
"x-xgen-atlascli": map[string]any{
"skip": false,
},
Comment thread
andreaangiolillo marked this conversation as resolved.
},
},
})),
},
expectedOas: &openapi3.T{
Paths: openapi3.NewPaths(openapi3.WithPath("/test", &openapi3.PathItem{
Get: &openapi3.Operation{
OperationID: "testOperationID",
Summary: "testSummary",
Responses: openapi3.NewResponses(openapi3.WithName("200", &openapi3.Response{
Content: openapi3.Content{
"application/vnd.atlas.2025-01-01+json": {
Schema: &openapi3.SchemaRef{
Ref: "#/components/schemas/PaginatedAppUserView",
},
Extensions: map[string]any{
"x-gen-version": "2025-01-01",
},
},
},
})),
Tags: []string{"TestTag"},
Extensions: map[string]any{
"x-sunset": "9999-12-31",
"x-xgen-atlascli": map[string]any{
"skip": false,
},
"x-codeSamples": []codeSample{
{
Lang: "cURL",
Label: "Atlas CLI",
Source: "atlas api testTag testOperationId --help",
},
{
Lang: "go",
Label: "Go",
Source: "import (\n" +
"\t\"os\"\n \"context\"\n" + "\t\"log\"\n" +
"\tsdk \"go.mongodb.org/atlas-sdk/v20250101001/admin\"\n)\n\n" +
"func main() {\n" +
"\tctx := context.Background()\n" +
"\tclientID := os.Getenv(\"MONGODB_ATLAS_CLIENT_ID\")\n" +
"\tclientSecret := os.Getenv(\"MONGODB_ATLAS_CLIENT_SECRET\")\n\n" +
"\t// See https://dochub.mongodb.org/core/atlas-go-sdk-oauth\n" +
"\tclient, err := sdk.NewClient(sdk.UseOAuthAuth(clientID, clientSecret))\n\n" +
"\tif err != nil {\n" + "\t\tlog.Fatalf(\"Error: %v\", err)\n\t}\n\n" +
"\tparams = &sdk.TestOperationIDApiParams{}\n" +
"\tsdkResp, httpResp, err := client.TestTagApi.\n" +
"\t\tTestOperationIDWithParams(ctx, params).\n" +
"\t\tExecute()" + "\n}\n",
},
{
Lang: "cURL",
Label: "curl (Service Accounts)",
Source: "curl --include --header \"Authorization: Bearer ${ACCESS_TOKEN}\" \\\n " +
"--header \"Accept: application/vnd.atlas.2025-01-01+json\" \\\n " + "-X GET \"https://cloud.mongodb.com/test?pretty=true\"",
},
{
Lang: "cURL",
Label: "curl (Digest)",
Source: "curl --user \"${PUBLIC_KEY}:${PRIVATE_KEY}\" \\\n --digest --include \\\n " +
"--header \"Accept: application/vnd.atlas.2025-01-01+json\" \\\n " + "-X GET \"https://cloud.mongodb.com/test?pretty=true\"",
},
},
},
},
})),
},
},
{
name: "stable api with x-xgen-atlascli skips the Atlas CLI code sample",
version: "2025-01-01",
oas: &openapi3.T{
Paths: openapi3.NewPaths(openapi3.WithPath("/test", &openapi3.PathItem{
Get: &openapi3.Operation{
OperationID: "testOperationID",
Summary: "testSummary",
Responses: openapi3.NewResponses(openapi3.WithName("200", &openapi3.Response{
Content: openapi3.Content{
"application/vnd.atlas.2025-01-01+json": {
Schema: &openapi3.SchemaRef{
Ref: "#/components/schemas/PaginatedAppUserView",
},
Extensions: map[string]any{
"x-gen-version": "2025-01-01",
},
},
},
})),
Tags: []string{"TestTag"},
Extensions: map[string]any{
"x-sunset": "9999-12-31",
"x-xgen-atlascli": map[string]any{
"skip": true,
},
},
},
})),
},
expectedOas: &openapi3.T{
Paths: openapi3.NewPaths(openapi3.WithPath("/test", &openapi3.PathItem{
Get: &openapi3.Operation{
OperationID: "testOperationID",
Summary: "testSummary",
Responses: openapi3.NewResponses(openapi3.WithName("200", &openapi3.Response{
Content: openapi3.Content{
"application/vnd.atlas.2025-01-01+json": {
Schema: &openapi3.SchemaRef{
Ref: "#/components/schemas/PaginatedAppUserView",
},
Extensions: map[string]any{
"x-gen-version": "2025-01-01",
},
},
},
})),
Tags: []string{"TestTag"},
Extensions: map[string]any{
"x-sunset": "9999-12-31",
"x-xgen-atlascli": map[string]any{
"skip": true,
},
"x-codeSamples": []codeSample{
{
Lang: "go",
Label: "Go",
Source: "import (\n" +
"\t\"os\"\n \"context\"\n" + "\t\"log\"\n" +
"\tsdk \"go.mongodb.org/atlas-sdk/v20250101001/admin\"\n)\n\n" +
"func main() {\n" +
"\tctx := context.Background()\n" +
"\tclientID := os.Getenv(\"MONGODB_ATLAS_CLIENT_ID\")\n" +
"\tclientSecret := os.Getenv(\"MONGODB_ATLAS_CLIENT_SECRET\")\n\n" +
"\t// See https://dochub.mongodb.org/core/atlas-go-sdk-oauth\n" +
"\tclient, err := sdk.NewClient(sdk.UseOAuthAuth(clientID, clientSecret))\n\n" +
"\tif err != nil {\n" + "\t\tlog.Fatalf(\"Error: %v\", err)\n\t}\n\n" +
"\tparams = &sdk.TestOperationIDApiParams{}\n" +
"\tsdkResp, httpResp, err := client.TestTagApi.\n" +
"\t\tTestOperationIDWithParams(ctx, params).\n" +
"\t\tExecute()" + "\n}\n",
},
{
Lang: "cURL",
Label: "curl (Service Accounts)",
Source: "curl --include --header \"Authorization: Bearer ${ACCESS_TOKEN}\" \\\n " +
"--header \"Accept: application/vnd.atlas.2025-01-01+json\" \\\n " + "-X GET \"https://cloud.mongodb.com/test?pretty=true\"",
},
{
Lang: "cURL",
Label: "curl (Digest)",
Source: "curl --user \"${PUBLIC_KEY}:${PRIVATE_KEY}\" \\\n --digest --include \\\n " +
"--header \"Accept: application/vnd.atlas.2025-01-01+json\" \\\n " + "-X GET \"https://cloud.mongodb.com/test?pretty=true\"",
},
},
},
},
})),
},
},
}

for _, tt := range testCases {
Expand Down
Loading