Skip to content

Commit

Permalink
Fixes for generated docs (#920)
Browse files Browse the repository at this point in the history
* Fixes for generated doc

- Avoid generating `#Examples` when no examples exist
- Fix typo

* Split out client customizations

* Update changelogs

* Fix generated READMEs
  • Loading branch information
rcoh authored Dec 2, 2021
1 parent ded8818 commit 88fc768
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 23 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
vNext (Month Day, Year)
=======================
**New this week**
- Fix typos in module documentation for generated crates (smithy-rs#920)

**Breaking changes**

Expand Down
1 change: 1 addition & 0 deletions aws/SDK_CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
vNext (Month Day, Year)
=======================
**New this release**
- Fix typos in module documentation for generated crates (smithy-rs#920)

v0.2.0 (December 2nd, 2021)
===========================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class AwsReadmeDecorator : RustCodegenDecorator {
"""
# $moduleName
**Please Note: The SDK is currently released as an alpha and is intended strictly for
**Please Note: The SDK is currently in Developer Preview and is intended strictly for
feedback purposes only. Do not use this SDK for production workloads.**
""".trimIndent() +
"\n\n$description\n\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,12 @@ fun writable(w: Writable): Writable = w

fun writable(w: String): Writable = writable { rust(w) }

fun Writable.isEmpty(): Boolean {
val writer = RustWriter.root()
this(writer)
return writer.toString() == RustWriter.root().toString()
}

class RustWriter private constructor(
private val filename: String,
val namespace: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import software.amazon.smithy.codegen.core.ReservedWordSymbolProvider
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.shapes.ServiceShape
import software.amazon.smithy.rust.codegen.rustlang.RustReservedWordSymbolProvider
import software.amazon.smithy.rust.codegen.smithy.customizations.ClientCustomizations
import software.amazon.smithy.rust.codegen.smithy.customize.CombinedCodegenDecorator
import java.util.logging.Level
import java.util.logging.Logger
Expand All @@ -31,7 +32,7 @@ class RustCodegenPlugin : SmithyBuildPlugin {
// - location (e.g. the mutate section of an operation)
// - context (e.g. the of the operation)
// - writer: The active RustWriter at the given location
val codegenDecorator = CombinedCodegenDecorator.fromClasspath(context)
val codegenDecorator = CombinedCodegenDecorator.fromClasspath(context, ClientCustomizations())

// CodegenVisitor is the main driver of code generation that traverses the model and generates code
CodegenVisitor(context, codegenDecorator).execute()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/

package software.amazon.smithy.rust.codegen.smithy.customizations

import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsCustomization

/**
* Customizations that apply only to generated clients
*/
class ClientCustomizations : RustCodegenDecorator {
override val name: String = "ClientCustomizations"
override val order: Byte = 0

override fun libRsCustomizations(
codegenContext: CodegenContext,
baseCustomizations: List<LibRsCustomization>
): List<LibRsCustomization> {
return baseCustomizations + ClientDocsGenerator()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/

package software.amazon.smithy.rust.codegen.smithy.customizations

import software.amazon.smithy.rust.codegen.rustlang.Writable
import software.amazon.smithy.rust.codegen.rustlang.containerDocs
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsCustomization
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsSection

class ClientDocsGenerator : LibRsCustomization() {
override fun section(section: LibRsSection): Writable {
return when (section) {
is LibRsSection.ModuleDocumentation -> if (section.subsection == LibRsSection.CrateOrganization) {
crateLayout()
} else emptySection
else -> emptySection
}
}
}

private fun crateLayout(): Writable = writable {
containerDocs(
"""
The entry point for most customers will be [`Client`]. [`Client`] exposes one method for each API offered
by the service.
Some APIs require complex or nested arguments. These exist in [`model`].
Lastly, errors that can be returned by the service are contained within [`error`]. [`Error`] defines a meta
error encompassing all possible errors that can be returned by the service.
The other modules within this crate are not required for normal usage.
""".trimEnd()
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,15 @@ open class CombinedCodegenDecorator(decorators: List<RustCodegenDecorator>) : Ru

companion object {
private val logger = Logger.getLogger("RustCodegenSPILoader")
fun fromClasspath(context: PluginContext): CombinedCodegenDecorator {
fun fromClasspath(context: PluginContext, vararg extras: RustCodegenDecorator): CombinedCodegenDecorator {
val decorators = ServiceLoader.load(
RustCodegenDecorator::class.java,
context.pluginClassLoader.orElse(RustCodegenDecorator::class.java.classLoader)
)
.onEach {
logger.info("Adding Codegen Decorator: ${it.javaClass.name}")
}.toList()
return CombinedCodegenDecorator(decorators + RequiredCustomizations() + FluentClientDecorator())
return CombinedCodegenDecorator(decorators + RequiredCustomizations() + FluentClientDecorator() + extras)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import software.amazon.smithy.rust.codegen.rustlang.RustModule
import software.amazon.smithy.rust.codegen.rustlang.RustWriter
import software.amazon.smithy.rust.codegen.rustlang.containerDocs
import software.amazon.smithy.rust.codegen.rustlang.escape
import software.amazon.smithy.rust.codegen.rustlang.isEmpty
import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.RustSettings
import software.amazon.smithy.rust.codegen.smithy.customize.NamedSectionGenerator
import software.amazon.smithy.rust.codegen.smithy.customize.Section
Expand All @@ -22,6 +22,10 @@ sealed class LibRsSection(name: String) : Section(name) {
object Attributes : LibRsSection("Attributes")
data class ModuleDocumentation(val subsection: String) : LibRsSection("ModuleDocumentation")
object Body : LibRsSection("Body")
companion object {
val Examples = "Examples"
val CrateOrganization = "CrateOrganization"
}
}

typealias LibRsCustomization = NamedSectionGenerator<LibRsSection>
Expand All @@ -43,26 +47,16 @@ class LibRsGenerator(
val libraryDocs = settings.getService(model).getTrait<DocumentationTrait>()?.value ?: settings.moduleName
containerDocs(escape(libraryDocs))
// TODO: replace "service" below with the title trait
containerDocs(
"""
## Crate Organization
The entry point for most customers will be [`Client`]. [`Client`] exposes one method for each API offered
by the service.
Some APIs require complex or nested arguments. These exist in [`model`].
Lastly, errors that can be returned by the service are contained within [`error`]. [`Error`] defines a meta
error encompassing all possible errors that can be returned by the service.
The other modules within this crate and not required for normal usage.
"""
)
val crateLayout = customizations.map { it.section(LibRsSection.ModuleDocumentation(LibRsSection.CrateOrganization)) }.filter { !it.isEmpty() }
if (crateLayout.isNotEmpty()) {
containerDocs("\n## Crate Organization")
crateLayout.forEach { it(this) }
}

val examples = customizations.map { it.section(LibRsSection.ModuleDocumentation("Examples")) }
.filter { it != writable { } }
val examples = customizations.map { it.section(LibRsSection.ModuleDocumentation(LibRsSection.Examples)) }
.filter { section -> !section.isEmpty() }
if (examples.isNotEmpty() || settings.examplesUri != null) {
containerDocs("## Examples")
containerDocs("\n## Examples")
examples.forEach { it(this) }

// TODO: Render a basic example for all crates (eg. select first operation and render an example of usage)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package software.amazon.smithy.rust.lang

import io.kotest.matchers.collections.shouldContain
import io.kotest.matchers.shouldBe
import io.kotest.matchers.string.shouldContain
import io.kotest.matchers.string.shouldContainOnlyOnce
import org.junit.jupiter.api.Test
Expand All @@ -18,7 +19,9 @@ import software.amazon.smithy.rust.codegen.rustlang.CargoDependency
import software.amazon.smithy.rust.codegen.rustlang.RustType
import software.amazon.smithy.rust.codegen.rustlang.RustWriter
import software.amazon.smithy.rust.codegen.rustlang.docs
import software.amazon.smithy.rust.codegen.rustlang.isEmpty
import software.amazon.smithy.rust.codegen.rustlang.rustBlock
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.testutil.asSmithyModel
import software.amazon.smithy.rust.codegen.testutil.compileAndRun
Expand Down Expand Up @@ -102,4 +105,10 @@ class RustWriterTest {
sut.docs("A link! #D", symbol)
sut.toString() shouldContain "/// A link! [`Foo`](crate::model::Foo)"
}

@Test
fun `empty writable`() {
val w = writable {}
w.isEmpty() shouldBe true
}
}

0 comments on commit 88fc768

Please sign in to comment.