Skip to content

Commit

Permalink
Added omit_header argument for Spec Insert components
Browse files Browse the repository at this point in the history
(Some minor refactoring to DRY the code as well)

Signed-off-by: Theo Truong <[email protected]>
  • Loading branch information
nhtruong committed Nov 15, 2024
1 parent f8926c0 commit 9970cea
Show file tree
Hide file tree
Showing 13 changed files with 91 additions and 80 deletions.
101 changes: 61 additions & 40 deletions DEVELOPER_GUIDE.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
# Developer guide
- [Introduction](#introduction)
- [Starting the Jekyll server locally](#starting-the-jekyll-server-locally)
- [Using spec-insert Jekyll plugin](#using-spec-insert-jekyll-plugin)
- [Insert Query Parameters](#insert-query-parameters)
- [Insert Path Parameters](#insert-path-parameters)
- [Insert Paths and HTTP Methods](#insert-paths-and-http-methods)
- [Ignored files and folders](#ignored-files-and-folders)
- [CI/CD](#cicd)
- [Introduction](#introduction)
- [Starting the Jekyll server locally](#starting-the-jekyll-server-locally)
- [Using the spec-insert Jekyll plugin](#using-the-spec-insert-jekyll-plugin)
- [Ignoring files and folders](#ignoring-files-and-folders)
- [CI/CD](#cicd)
- [Spec insert components](#spec-insert-components)
- [Query parameters](#query-parameters)
- [Path parameters](#path-parameters)
- [Paths and HTTP methods](#paths-and-http-methods)

## Introduction

The `.md` documents in this repository are rendered into HTML pages using [Jekyll](https://jekyllrb.com/). These HTML pages are hosted on [opensearch.org](https://opensearch.org/docs/latest/).

## Starting the Jekyll server locally
You can run the Jekyll server locally to view the rendered HTML pages after making changes to the markdown files:
- Install [Ruby](https://www.ruby-lang.org/en/documentation/installation/) 3.1.0 or later for your operating system.
- Install the required gems by running `bundle install`.
- Run `bundle exec jekyll serve` to start the Jekyll server locally. (This can take several minutes to be ready.)
- Open your browser and navigate to `http://localhost:4000` to view the rendered HTML pages.
You can run the Jekyll server locally to view the rendered HTML pages using the following steps:

1. Install [Ruby](https://www.ruby-lang.org/en/documentation/installation/) 3.1.0 or later for your operating system.
2. Install the required gems by running `bundle install`.
3. Run `bundle exec jekyll serve` to start the Jekyll server locally (this can take several minutes to complete).
4. Open your browser and navigate to `http://localhost:4000` to view the rendered HTML pages.

## Using spec-insert Jekyll plugin
The `spec-insert` Jekyll plugin is used to insert API components into the markdown files. The plugin downloads the [latest OpenSearch Specification](https://github.com/opensearch-project/opensearch-api-specification) and renders the API components from the spec. This aims to reduce the manual effort required to keep the documentation up-to-date.
## Using the `spec-insert` Jekyll plugin
The `spec-insert` Jekyll plugin is used to insert API components into Markdown files. The plugin downloads the [latest OpenSearch specification](https://github.com/opensearch-project/opensearch-api-specification) and renders the API components from the spec. This aims to reduce the manual effort required to keep the documentation up to date.

To use this plugin, make sure that you have installed Ruby 3.1.0 or later and the required gems by running `bundle install`.

Edit your markdown file and insert the following snippet where you want an API component to be rendered:
Edit your Markdown file and insert the following snippet where you want render an API component:

```markdown
<!-- spec_insert_start
api: <API_NAME>
component: <COMPONENT_NAME>
other_param: <OTHER_PARAM>
other_argument: <OTHER_ARGUMENT>
-->

This is where the API component will be inserted.
Expand All @@ -37,26 +41,39 @@ Everything between the `spec_insert_start` and `spec_insert_end` tags will be ov
<!-- spec_insert_end -->
```

Then run the follow Jekyll command to render the API components:
Then run the following Jekyll command to render the API components:
```shell
bundle exec jekyll spec-insert
```

If you are working on multiple markdown files and do not want to keep running the `jekyll spec-insert` command, you can add the `--watch` (or `-W`) flag to the command to watch for changes in the markdown files and automatically render the API components:
If you are working on multiple Markdown files and do not want to keep running the `jekyll spec-insert` command, you can add the `--watch` (or `-W`) flag to the command to watch for changes in the Markdown files and automatically render the API components:

```shell
bundle exec jekyll spec-insert --watch
```

Note that depending on the text editor you are using to edit the markdown, you may need to manually reload the file from disk to see the changes applied by the plugin if the editor does not automatically reload the file periodically.
Depending on the text editor you are using, you may need to manually reload the file from disk to see the changes applied by the plugin if the editor does not automatically reload the file periodically.

The plugin will pull the newest OpenSearch Spec from its [repository](https://github.com/opensearch-project/opensearch-api-specification) if the spec file does not exist locally or if it is older than 24 hours. To tell the plugin to always pull the newest spec, you can add the `--refresh-spec` (or `-R`) flag to the command:
The plugin will pull the newest OpenSearch API spec from its [repository](https://github.com/opensearch-project/opensearch-api-specification) if the spec file does not exist locally or if it is older than 24 hours. To tell the plugin to always pull the newest spec, you can add the `--refresh-spec` (or `-R`) flag to the command:

```shell
bundle exec jekyll spec-insert --refresh-spec
```

### Inserting query parameters
To insert query parameters table of the `cat.indices` API, use the following snippet:
### Ignoring files and folders
The `spec-insert` plugin ignores all files and folders listed in the [./_config.yml#exclude](./_config.yml) list, which is also the list of files and folders that Jekyll ignores.

## CI/CD
The `spec-insert` plugin is run as part of the CI/CD pipeline to ensure that the API components are up to date in the documentation. This is performed through the [update-api-components.yml](.github/workflows/update-api-components.yml) GitHub Actions workflow, which creates a pull request containing the updated API components every Sunday.

## Spec insert components
All spec insert components accept the following arguments:
- `api` (String; required): The name of the API to render the component from. This is equivalent to the `x-operation-group` field in the OpenSearch OpenAPI Spec.
- `component` (String; required): The name of the component to render (e.g., `query_parameters`, `path_parameters`, or `paths_and_http_methods`).
- `omit_header` (Boolean; default is `false`): If set to `true`, the markdown header of the component (e.g. `## Query parameters`) will not be rendered.

### Query parameters
To insert the API query parameters table of the `cat.indices` API, use the following snippet:
```markdown
<!-- spec_insert_start
api: cat.indices
Expand All @@ -65,10 +82,23 @@ component: query_parameters
<!-- spec_insert_end -->
```

- This will insert the query parameters of the `cat.indices` API into the markdown file 3 default columns: `Parameter`, `Type`, and `Description`. There are 5 columns that can be inserted: `Parameter`, `Type`, `Description`, `Required`, and `Default`. When `Required`/`Default` is not chosen, the info will be written in the `Description` column.
- This component accepts `include_global` (Boolean, default to `false`) argument to include global query parameters in the table.
- This component accepts `include_deprecated` (Boolean, default to `true`) argument to include deprecated parameters in the table.
- This component accepts `pretty` (Boolean, default to `false`) argument to render the table in the pretty format instead of the compact format.
This will insert the query parameters of the `cat.indices` API into the `.md` file with three default columns: `Parameter`, `Type`, and `Description`. You can customize the query parameters table by adding the `columns` argument which accepts a comma-separated list of column names. The available column names are:

- `Parameter`
- `Type`
- `Description`
- `Required`
- `Default`

_When `Required`/`Default` is not chosen, the information will be written in the `Description` column._

Check failure on line 93 in DEVELOPER_GUIDE.md

View workflow job for this annotation

GitHub Actions / style-job

[vale] reported by reviewdog 🐶 [OpenSearch.SpacingSlash] When using '/' between words, do not insert space on either side of it. Raw Output: {"message": "[OpenSearch.SpacingSlash] When using '/' between words, do not insert space on either side of it.", "location": {"path": "DEVELOPER_GUIDE.md", "range": {"start": {"line": 93, "column": 1}}}, "severity": "ERROR"}

You can also customize this component with the following settings:

- `include_global` (Boolean; default is `false`): Includes global query parameters in the table.
- `include_deprecated` (Boolean; default is `true`): Includes deprecated parameters in the table.
- `pretty` (Boolean; default is `false`): Renders the table in the pretty format instead of the compact format.

The following snippet inserts the specified columns into the query parameters table:

```markdown
<!-- spec_insert_start
Expand All @@ -81,8 +111,7 @@ pretty: true
<!-- spec_insert_end -->
```

### Inserting path parameters

### Path parameters
To insert path parameters table of the `indices.create` API, use the following snippet:
```markdown
<!-- spec_insert_start
Expand All @@ -91,22 +120,14 @@ component: path_parameters
-->
<!-- spec_insert_end -->
```

This table behaves the same as the query parameters table except that it does not accept the `include_global` argument.

### Inserting paths and HTTP methods

To insert paths and HTTP methods of the `search` API, use the following snippet:
### Paths and HTTP methods
To insert paths and HTTP methods for the `search` API, use the following snippet:
```markdown
<!-- spec_insert_start
api: search
component: paths_and_http_methods
-->
<!-- spec_insert_end -->
```

### Ignoring files and folders
The `spec-insert` plugin ignores all files and folders listed in the [./_config.yml#exclude](./_config.yml) list, which is also the list of files and folders that Jekyll ignores.

### CI/CD
The `spec-insert` plugin is run as part of the CI/CD pipeline to ensure that the API components are up-to-date in the documentation. This is done through the [update-api-components.yml](.github/workflows/update-api-components.yml) GitHub Action workflow that creates a pull request with the updated API components every Sunday.
```
5 changes: 5 additions & 0 deletions spec-insert/lib/insert_arguments.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ def include_deprecated
parse_boolean(@raw['include_deprecated'], default: true)
end

# @return [Boolean]
def omit_header
parse_boolean(@raw['omit_header'], default: false)
end

private

# @param [String] value comma-separated array
Expand Down
14 changes: 8 additions & 6 deletions spec-insert/lib/renderers/base_mustache_renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
class BaseMustacheRenderer < Mustache
self.template_path = "#{__dir__}/templates"

def initialize(output_file = nil)
@output_file = output_file
super
# @param [Action] action API Action
# @param [InsertArguments] args
def initialize(action, args)
super()
@action = action
@args = args
end

def generate
raise 'Output file not specified' unless @output_file
@output_file&.write(render)
def omit_header
@args.omit_header
end
end
1 change: 0 additions & 1 deletion spec-insert/lib/renderers/parameter_table_renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ def initialize(parameters, args)
@pretty = args.pretty
@parameters = parameters
@parameters = @parameters.reject(&:deprecated) unless args.include_deprecated
@parameters += Parameter.global if args.include_global
@parameters = @parameters.sort_by { |arg| [arg.required ? 0 : 1, arg.deprecated ? 1 : 0, arg.name] }
end

Expand Down
11 changes: 2 additions & 9 deletions spec-insert/lib/renderers/path_parameters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,8 @@
class PathParameters < BaseMustacheRenderer
self.template_file = "#{__dir__}/templates/path_parameters.mustache"

# @param [Action] action API Action
# @param [InsertArguments] args
def initialize(action, args)
super(nil)
@params = action.arguments.select { |arg| arg.location == ArgLocation::PATH }
@args = args
end

def table
ParameterTableRenderer.new(@params, @args).render
params = @action.arguments.select { |arg| arg.location == ArgLocation::PATH }
ParameterTableRenderer.new(params, @args).render
end
end
6 changes: 0 additions & 6 deletions spec-insert/lib/renderers/paths_and_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@
class PathsAndMethods < BaseMustacheRenderer
self.template_file = "#{__dir__}/templates/paths_and_methods.mustache"

# @param [Action] action API Action
def initialize(action)
super
@action = action
end

def operations
ljust = @action.operations.map { |op| op.http_verb.length }.max
@action.operations
Expand Down
16 changes: 3 additions & 13 deletions spec-insert/lib/renderers/query_parameters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,9 @@
class QueryParameters < BaseMustacheRenderer
self.template_file = "#{__dir__}/templates/query_parameters.mustache"

# @param [Action] action API Action
# @param [InsertArguments] args
def initialize(action, args)
super(nil)
@params = action.arguments.select { |arg| arg.location == ArgLocation::QUERY }
@args = args
end

def table
ParameterTableRenderer.new(@params, @args).render
end

def optional
@params.none?(&:required)
params = @action.arguments.select { |arg| arg.location == ArgLocation::QUERY }
params += Parameter.global if @args.include_global
ParameterTableRenderer.new(params, @args).render
end
end
8 changes: 4 additions & 4 deletions spec-insert/lib/renderers/spec_insert.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ class SpecInsert < BaseMustacheRenderer

# @param [Array<String>] arg_lines the lines between "<!-- doc_insert_start" and "-->"
def initialize(arg_lines)
super
@args = InsertArguments.new(arg_lines)
@action = Action.actions[@args.api]
args = InsertArguments.new(arg_lines)
action = Action.actions[args.api]
super(action, args)
raise SpecInsertError, '`api` argument not specified.' unless @args.api
raise SpecInsertError, "API Action '#{@args.api}' does not exist in the spec." unless @action
end
Expand All @@ -34,7 +34,7 @@ def content
when :path_parameters
PathParameters.new(@action, @args).render
when :paths_and_http_methods
PathsAndMethods.new(@action).render
PathsAndMethods.new(@action, @args).render
else
raise SpecInsertError, "Invalid component: #{@args.component}"
end
Expand Down
2 changes: 2 additions & 0 deletions spec-insert/lib/renderers/templates/path_parameters.mustache
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
{{^omit_header}}
## Path parameters
{{/omit_header}}
{{{table}}}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{{^omit_header}}
## Paths and HTTP methods
{{/omit_header}}
```json
{{#operations}}
{{{verb}}} {{{path}}}
Expand Down
2 changes: 2 additions & 0 deletions spec-insert/lib/renderers/templates/query_parameters.mustache
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{{^omit_header}}
## Query parameters
{{#optional}}
All query parameters are optional.
{{/optional}}
{{/omit_header}}
{{{table}}}
2 changes: 1 addition & 1 deletion spec-insert/spec/_fixtures/expected_output/param_tables.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ Query Parameters Example with only Parameter and Description Columns
api: search
component: query_parameters
columns: Parameter, Description
omit_header: true
-->
## Query parameters
Parameter | Description
:--- | :---
`analyze_wildcard` | **(Required)** If true, wildcard and prefix queries are analyzed. This parameter can only be used when the q query string parameter is specified.
Expand Down
1 change: 1 addition & 0 deletions spec-insert/spec/_fixtures/input/param_tables.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Query Parameters Example with only Parameter and Description Columns
api: search
component: query_parameters
columns: Parameter, Description
omit_header: true
-->
THIS
TEXT
Expand Down

0 comments on commit 9970cea

Please sign in to comment.