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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "openapi-lint"
description = "Validate an OpenAPI schema against some rules"
version = "0.4.0"
version = "0.5.0"
edition = "2021"
license = "Apache-2.0"
repository = "https://github.com/oxidecomputer/openapi-lint/"
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,7 @@ easy to accidentally allow internally-relevant documentation leak out as
externally-visible in the OpenAPI document. It's not possible to simply infer
this from text alone, but we do look for shibboleths such as a Rust path
delimeter (`::`) and bracketed expressions with no subsequent parentheses
(`[title](http://link.dest)` being reasonable).
(`[title](http://link.dest)` being reasonable).

Additionally, operation summaries (the OpenAPI `summary` field) should be
short phrases and **should not end with a period**.
34 changes: 34 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,21 @@ impl Validator {
let responses = spec
.operations()
.flat_map(|(_, _, op)| self.validate_operation_response(spec, op));
let op_summaries = if external {
spec.operations()
.filter_map(|path_method_op| self.validate_operation_summary(path_method_op))
.collect()
} else {
Vec::new()
};
let op_docs = if external {
spec.operations()
.flat_map(|(_, _, op)| op.description.as_ref().and_then(|s| check_doc_string(s)))
.collect()
} else {
Vec::new()
};

let named_schemas = spec.components.iter().flat_map(|components| {
components
.schemas
Expand All @@ -90,6 +98,7 @@ impl Validator {
.chain(parameters)
.chain(responses)
.chain(named_schemas)
.chain(op_summaries)
.chain(op_docs)
.collect()
}
Expand Down Expand Up @@ -261,6 +270,31 @@ impl Validator {
}
}

fn validate_operation_summary(
&self,
path_method_op: (&str, &str, &Operation),
) -> Option<String> {
let (path, method, op) = path_method_op;

const INFO: &str = "For more info, see \
https://github.com/oxidecomputer/openapi-lint#rust-documentation";

if let Some(summary) = &op.summary {
// summaries should be short phrases and should not end with a period
if summary.trim_end().ends_with('.') {
let operation_id = op.operation_id.as_deref().unwrap_or("<unknown>");
return Some(format!(
"The operation for {} {} (operation_id: {}) has a summary \
(first line of doc comment) that ends with a period; \
summaries should not end with a period.\n{}",
path, method, operation_id, INFO,
));
}
}

None
}

fn validate_operation_parameters(&self, spec: &OpenAPI, op: &Operation) -> Vec<String> {
const INFO: &str = "For more info, see \
https://github.com/oxidecomputer/openapi-lint#naming";
Expand Down
1 change: 1 addition & 0 deletions src/tests/errors.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
},
"/hardware/racks": {
"get": {
"summary": "List racks in the system.",
"description": "List racks in the system.",
"operationId": "hardware_racks_get",
"parameters": [
Expand Down
5 changes: 4 additions & 1 deletion src/tests/errors.out
Original file line number Diff line number Diff line change
Expand Up @@ -5681,4 +5681,7 @@ The return type for unit_return was a trivial null.
For more info, see https://github.com/oxidecomputer/openapi-lint#trivial-null-response

The type "fake_id_sort_mode" has a name that is not PascalCase; to rename it add #[serde(rename = "FakeIdSortMode")]
For more info, see https://github.com/oxidecomputer/openapi-lint#naming
For more info, see https://github.com/oxidecomputer/openapi-lint#naming

The operation for /hardware/racks get (operation_id: hardware_racks_get) has a summary (first line of doc comment) that ends with a period; summaries should not end with a period.
For more info, see https://github.com/oxidecomputer/openapi-lint#rust-documentation
Loading