Skip to content

Commit

Permalink
Add --x-include option to the merger to support x-tested.
Browse files Browse the repository at this point in the history
  • Loading branch information
dblock committed May 10, 2024
1 parent 946114c commit 597c24b
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 190 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ jobs:
run: |-
mkdir -p ../build
npm install
# TODO: replace with ../spec ../build/opensearch-openapi.yaml
npm run merge -- --source ../min --output ../build/min.yaml
npm run merge -- --source ../spec --output ../build/opensearch-openapi.yaml --x-include=x-tested
- name: Build and Run Docker Container
run: |
Expand Down
43 changes: 0 additions & 43 deletions min/_global_parameters.yaml

This file was deleted.

4 changes: 0 additions & 4 deletions min/_info.yaml

This file was deleted.

1 change: 0 additions & 1 deletion min/_superseded_operations.yaml

This file was deleted.

68 changes: 0 additions & 68 deletions min/namespaces/_core.yaml

This file was deleted.

67 changes: 0 additions & 67 deletions min/schemas/_common.yaml

This file was deleted.

1 change: 1 addition & 0 deletions spec/namespaces/_core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ paths:
operationId: info.0
x-operation-group: info
x-version-added: '1.0'
x-tested: true
description: Returns basic information about the cluster.
externalDocs:
url: https://opensearch.org/docs/latest
Expand Down
2 changes: 1 addition & 1 deletion tools/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default [
{ selector: 'typeProperty', format: null }
],
'@typescript-eslint/no-confusing-void-expression': 'error',
'@typescript-eslint/no-dynamic-delete': 'error',
'@typescript-eslint/no-dynamic-delete': 'off',
'@typescript-eslint/no-invalid-void-type': 'error',
'@typescript-eslint/no-non-null-assertion': 'error',
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
Expand Down
24 changes: 23 additions & 1 deletion tools/merger/OpenApiMerger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import GlobalParamsGenerator from './GlobalParamsGenerator'
// Create a single-file OpenAPI spec from multiple files for OpenAPI validation and programmatic consumption
export default class OpenApiMerger {
root_folder: string
options: { x_include: string[] }
spec: Record<string, any>

paths: Record<string, Record<string, OpenAPIV3.PathItemObject>> = {} // namespace -> path -> path_item_object
schemas: Record<string, Record<string, OpenAPIV3.SchemaObject>> = {} // category -> schema -> schema_object

constructor (root_folder: string) {
constructor (root_folder: string, options?: { x_include: string[] }) {
this.root_folder = fs.realpathSync(root_folder)
this.options = options ?? { x_include: [] }
this.spec = {
openapi: '3.1.0',
info: read_yaml(`${this.root_folder}/_info.yaml`, true),
Expand Down Expand Up @@ -46,6 +48,7 @@ export default class OpenApiMerger {
const spec = read_yaml(`${folder}/${file}`)
this.redirect_refs_in_namespace(spec)
this.spec.paths = { ...this.spec.paths, ...spec.paths }
this.filter_methods(spec)
this.spec.components.parameters = { ...this.spec.components.parameters, ...spec.components.parameters }
this.spec.components.responses = { ...this.spec.components.responses, ...spec.components.responses }
this.spec.components.requestBodies = { ...this.spec.components.requestBodies, ...spec.components.requestBodies }
Expand Down Expand Up @@ -119,4 +122,23 @@ export default class OpenApiMerger {
const gen = new SupersededOpsGenerator(this.root_folder)
gen.generate(this.spec)
}

filter_methods (paths: any): void {
for (const x_include_value of this.options.x_include) {
this.#filter_methods_with_key(paths, x_include_value)
}
}

#filter_methods_with_key (paths: any, key: string): void {
Object.entries(this.spec.paths as Document).forEach(([path, path_item]) => {
Object.entries(path_item as Document).forEach(([method, method_spec]) => {
if (method_spec[key] === undefined) {
delete (this.spec.paths[path][method])
if (Object.keys(this.spec.paths[path] as Document).length === 0) {
delete (this.spec.paths[path])
}
}
})
})
}
}
3 changes: 2 additions & 1 deletion tools/merger/merge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ const command = new Command()
.description('Merges the multi-file OpenSearch spec into a single file for programmatic use.')
.addOption(new Option('-s, --source <path>', 'path to the root folder of the multi-file spec').default(resolve(__dirname, '../../spec')))
.addOption(new Option('-o, --output <path>', 'output file name').default(resolve(__dirname, '../../build/opensearch-openapi.yaml')))
.addOption(new Option('--x-include <option...>', 'only include paths with x-values defined, e.g. --x-include x-tested').default([]))
.allowExcessArguments(false)
.parse()

const opts = command.opts()
const merger = new OpenApiMerger(opts.source)
const merger = new OpenApiMerger(opts.source, { x_include: opts.xInclude })
console.log(`Merging ${opts.source} into ${opts.output} ...`)
merger.merge(opts.output)
console.log('Done.')
12 changes: 10 additions & 2 deletions tools/test/merger/OpenApiMerger.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ import fs from 'fs'
test('merge()', async () => {
const merger = new OpenApiMerger('./test/merger/fixtures/spec/')
merger.merge('./test/merger/opensearch-openapi.yaml')
expect(fs.readFileSync('./test/merger/fixtures/expected.yaml', 'utf8'))
.toEqual(fs.readFileSync('./test/merger/opensearch-openapi.yaml', 'utf8'))
expect(fs.readFileSync('./test/merger/opensearch-openapi.yaml', 'utf8'))
.toEqual(fs.readFileSync('./test/merger/fixtures/expected.yaml', 'utf8'))
fs.unlinkSync('./test/merger/opensearch-openapi.yaml')
})

test('merge(x-ignorable)', async () => {
const merger = new OpenApiMerger('./test/merger/fixtures/spec/', { x_include: ['x-xyz'] })
merger.merge('./test/merger/opensearch-openapi-x-xyz.yaml')
expect(fs.readFileSync('./test/merger/opensearch-openapi-x-xyz.yaml', 'utf8'))
.toEqual(fs.readFileSync('./test/merger/fixtures/expected-x-xyz.yaml', 'utf8'))
fs.unlinkSync('./test/merger/opensearch-openapi-x-xyz.yaml')
})
81 changes: 81 additions & 0 deletions tools/test/merger/fixtures/expected-x-xyz.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
openapi: 3.1.0
info:
title: OpenSearch API
description: OpenSearch API
version: 1.0.0
paths:
/{index}:
post:
parameters:
- $ref: '#/components/parameters/indices.create::path.index'
- $ref: '#/components/parameters/indices.create::query.pretty'
- $ref: '#/components/parameters/_global::query.human'
requestBody:
$ref: '#/components/requestBodies/indices.create'
responses:
'200':
$ref: '#/components/responses/indices.create@200'
x-xyz: true
components:
parameters:
_global::query.human:
name: human
in: query
description: Whether to return human readable values for statistics.
schema:
type: boolean
default: true
x-global: true
adopt::path.animal:
name: animal
in: path
schema:
$ref: '#/components/schemas/animals:Animal'
adopt::path.docket:
name: docket
in: path
schema:
type: number
indices.create::path.index:
name: index
in: path
schema:
type: string
indices.create::query.pretty:
name: pretty
in: query
schema:
type: boolean
requestBodies:
adopt: {}
indices.create: {}
responses:
adopt@200:
description: ''
application/json:
schema:
type: object
indices.create@200:
description: ''
application/json:
schema:
type: object
schemas:
actions:Bark:
type: string
actions:Meow:
type: string
animals:Animal:
oneOf:
- $ref: '#/components/schemas/animals:Dog'
- $ref: '#/components/schemas/animals:Cat'
animals:Cat:
type: object
properties:
meow:
$ref: '#/components/schemas/actions:Meow'
animals:Dog:
type: object
properties:
bark:
$ref: '#/components/schemas/actions:Bark'
1 change: 1 addition & 0 deletions tools/test/merger/fixtures/expected.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ paths:
responses:
'200':
$ref: '#/components/responses/indices.create@200'
x-xyz: true
/adopt/{animal}/dockets/{docket}:
get:
operationId: adopt.0
Expand Down
1 change: 1 addition & 0 deletions tools/test/merger/fixtures/spec/namespaces/indices.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ paths:
responses:
'200':
$ref: '#/components/responses/indices.create@200'
x-xyz: true
components:
requestBodies:
indices.create: {}
Expand Down

0 comments on commit 597c24b

Please sign in to comment.