Skip to content

Commit

Permalink
Merge pull request #261 from ably/add-api-reference
Browse files Browse the repository at this point in the history
Port api reference to specification repo
  • Loading branch information
SimonWoolf authored Jan 7, 2025
2 parents cc6c60f + 64b2746 commit 268fbc4
Show file tree
Hide file tree
Showing 3 changed files with 1,249 additions and 8 deletions.
68 changes: 68 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,74 @@ Historically, before the above guidance was established - in particular around _
This left us open to the problem that client library references to spec items could end up semantically invalid if that spec point was re-used later.
For example, if `XXX1a` and `XXX1c` exist but `XXX1b` doesn’t because it was removed in the past (prior to this guidance being established), then we should introduce `XXX1d` for the new spec item rather than re-using `XXX1b`.

## SDK API docstrings

The `api-docstrings.md` file is a set of language-agnostic reference API commentaries for SDK developers to use when adding docstring comments to Ably SDKs. For new fields, this file should be modified in the same PR that makes the spec changes for those fields.

Modifications should obey the following conventions:

### Table format

#### Classes

The table for each class contains the following columns:

```
| Method / Property | Parameter | Returns | Spec | Description |
```

* **Method/Property**: The full method signature (code formatted only where necessary, e.g. where it includes `<`, or property name.
* **Parameter**: Each parameter should have its own row and be code formatted.
* **Returns**: The return value should be code formatted and has its own row, after the parameters have been listed.
* **Spec**: The spec point related to the method or property.
* **Description**: The language-agnostic description that will form the docstrings.

#### Enums

The table for each enum contains the following columns:

```markdown
| Enum | Spec | Description |
```

* **Enum**: The name of each value for the enum.
* **Spec**: The spec point related to the enum.
* **Description**: The language-agnostic description that will form the docstrings.

### Conventions

The following conventions should be followed when adding a new method or property to the table:

* Use a verb with an `s` for method descriptions. Common uses are:
* `get` --> `retrieves`
* `subscribe` --> `registers (a listener)`
* `publish` --> `Publishes`
* The expression key-value pairs should be hyphenated.
* Parameters or returns that refer to another class are referred to in terms of objects, for example:
```
A [`Channels`]{@link Channels} object.
```
* Links to other classes/enums are written in the format:
```
[`<text>`]{@link <class>#<property>}
```
For example:
```
[`ClientOptions.logLevel`]{@link ClientOptions#logLevel}`
```
* If a method references its own class, it should just be code formatted, and not link to itself.
* Descriptions can link out to conceptual docs hosted on `ably.com/docs`, but should never link to the API references hosted there.
* A class or object should always be capitalized.
* Methods and parameters should always be lower-case.
* If adding a method/property to separate REST and realtime classes, ensure the descriptions are consistent (where possible).
* When a return value is returned in a paginated list, the description should link to the PaginatedResult class, as well as the class of whatever is returned.
* Items deprecated in the features spec should include the following text at the beginning of the description: `DEPRECATED: this <property/method> is deprecated and will be removed in a future version.`
* Default values should be listed in the description field.
* If a minimum or maximum value exists for a parameter then it should be listed in the description field.
* Time values should be referred to as `milliseconds since the Unix epoch` where applicable.
## Release Process
Use our standard [Release Process](https://github.com/ably/engineering/blob/main/sdk/releases.md#release-process), where:
Expand Down
49 changes: 41 additions & 8 deletions scripts/build
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ gemfile do
source 'https://rubygems.org'
gem 'RedCloth', '~> 4.3.2'
gem 'ruby-handlebars', '~> 0.4.1'
gem 'kramdown', '~> 2.4.0'
end
puts 'Gems installed and loaded.'

SOURCE_PATH = File.expand_path('../../textile', __FILE__)
SOURCE_EXTENSION = '.textile'
TEXTILE_EXTENSION = '.textile'
MARKDOWN_EXTENSION = '.md'
ROOT_SOURCE_NAME = 'index'
TEMPLATE_PATH = File.expand_path('../../templates/docs-textile.html.hbs', __FILE__)
OUTPUT_PATH = File.expand_path('../../output', __FILE__)
Expand Down Expand Up @@ -77,16 +79,19 @@ versions = YAML.load_file(META_PATH)['versions']
handlebars = Handlebars::Handlebars.new
template = handlebars.compile(File.read(TEMPLATE_PATH))

source_file_names = Dir.children(SOURCE_PATH).select {
|file_name| file_name.end_with? "#{SOURCE_EXTENSION}"
textile_file_names = Dir.children(SOURCE_PATH).select {
|file_name| file_name.end_with? "#{TEXTILE_EXTENSION}"
}.sort

# File names without '.textile' extension, and without the root 'index'.
plain_file_names = source_file_names.collect {
|file_name| file_name.delete_suffix(SOURCE_EXTENSION)
markdown_file_names = Dir.children(SOURCE_PATH).select {
|file_name| file_name.end_with? "#{MARKDOWN_EXTENSION}"
}.sort

plain_file_names = (textile_file_names + markdown_file_names).collect {
|file_name| file_name.delete_suffix(TEXTILE_EXTENSION).delete_suffix(MARKDOWN_EXTENSION)
} - [ROOT_SOURCE_NAME]

source_file_names.each do |file_name|
textile_file_names.each do |file_name|
print "#{file_name} ... "

# We could possibly have used the Handlebars gem we're using elsewhere for this, however it was barfing on features.textile for no clear reason.
Expand All @@ -96,7 +101,35 @@ source_file_names.each do |file_name|
.gsub(/\{\{\s*PROTOCOL_VERSION\s*\}\}/, versions['protocol'].to_s)

bodyHtml = RedCloth.new(textile, [:no_span_caps]).to_html(*REDCLOTH_RULES)
plain_file_name = file_name.delete_suffix(SOURCE_EXTENSION)
plain_file_name = file_name.delete_suffix(TEXTILE_EXTENSION)
is_root = (plain_file_name == ROOT_SOURCE_NAME)
html = template.call({
bodyContent: bodyHtml,
title: plain_file_name.capitalize(),
file_names: plain_file_names - [plain_file_name],
root_path: is_root ? '' : '../',
copyright: COPYRIGHT,
build_context_title: BUILD_CONTEXT_TITLE,
build_context_url: BUILD_CONTEXT_URL,
build_context_sha: BUILD_CONTEXT_SHA,
})
folder_path = is_root ? OUTPUT_PATH : File.join(OUTPUT_PATH, plain_file_name)
if !is_root
Dir.mkdir folder_path
end
File.write(File.join(folder_path, "index.html"), html)
puts "✓"
end

markdown_file_names.each do |file_name|
print "#{file_name} ... "

markdown_content = remove_frontmatter(File.read(File.join(SOURCE_PATH, file_name)))
.gsub(/\{\{\s*SPECIFICATION_VERSION\s*\}\}/, versions['specification'].to_s)
.gsub(/\{\{\s*PROTOCOL_VERSION\s*\}\}/, versions['protocol'].to_s)

bodyHtml = Kramdown::Document.new(markdown_content).to_html
plain_file_name = file_name.delete_suffix(MARKDOWN_EXTENSION)
is_root = (plain_file_name == ROOT_SOURCE_NAME)
html = template.call({
bodyContent: bodyHtml,
Expand Down
Loading

0 comments on commit 268fbc4

Please sign in to comment.