# airbnb.io/viaduct

This readme documents how to develop and deploy airbnb.io/viaduct.

## Stack

This is a Hugo/Docsy site. See the [Docsy documentation](https://www.docsy.dev/docs/getting-started/) for more information.

Ensure you have followed the [Docsy prerequisites](https://www.docsy.dev/docs/get-started/docsy-as-module/installation-prerequisites/).

### Customizations

#### Shortcodes

There are a few custom shortcodes in the `layouts/shortcodes` directory:


There are a few custom shortcodes in the `layouts/_shortcodes` directory:

* `github`: Embeds a GitHub file in the documentation.
    ```markdown
    {{< github file="tenant/api/src/main/kotlin/viaduct/api/TenantModule.kt" maxHeight=1000 >}}
    {{< github "tenant/api/src/main/kotlin/viaduct/api/TenantModule.kt" branch="jsmith--test" >}}
    ```
  Both named and positional parameters are supported.
  Parameters:
  * `file`: The URL of the GitHub file to embed. Optionally append a line range, e.g. `#L10-L20` to embed only those lines.
  * `maxHeight`: The maximum height of the embedded file. Defaults to 500px.
* `kdoc`: Embeds a KDoc link in the documentation. CI will verify that the link is valid. Currently only supports linking to classes, not functions or packages.
    ```markdown
    {{< kdoc viaduct.engine.api.execution.ResolverErrorReporter >}}
    ```
  returns:
    ```
    <a class="kdoc-link" href="$BASE_URL/apis/service/service/service-api/viaduct.service.api/-execution-input/"><code>ExecutionInput</code></a>
    ```
    ```markdown
    {{< kdoc viaduct.api.Resolver "@resolver" >}
    ```
  returns:
    ```
    <a class="kdoc-link" href="http://localhost:1313/apis/tenant-api/tenant-api/viaduct.api/-resolver/"><code>@resolver</code></a>
    ```
  Parameters:
  * First: The fully qualified name of the KDoc to link to.
  * Second: Display name (optional). Defaults to the class name. Must be wrapped in quotes if it contains special characters like `@`.

#### `codetag` shortcode

Code tags works along the source code, in any part of the source code you need to add a comment with the format :

```kotlin
//tag::NAME[LINES] Comment
```

Where NAME is the tag name that will be used in the documentation to reference the code snippet.
And LINES that is the amount of lines to include in the snippet, after this comment. If not specified will take 10 lines of code.
Comment is optional and can be used to describe the code snippet usage for developers.

Example:

In your code

```kotlin
//tag::VIADUCT_CONFIG_1[5] This is shown in service documentation
```

In the hugo service documentation

```md
{{< codetag path="demoapp/starwars/src/main/kotlin/viaduct/demoapp/starwars/config/ViaductConfig.kt" tag="VIADUCT_CONFIG_1" >}}
```

Where path is the path to the source code.

This will show the code in the document and also shows a link to the full file in GitHub.

> There is an optional `lang` parameter to specify the language for syntax highlighting. Default it is `kotlin`.

> There is an optional `count` parameter to specify the amount of lines to show.

#### `codefile` shortcode

Code file works simpler, it is just a code snippet of the whole file or a range of lines. No need to modify the source code.

```md
{{< codefile path="demoapp/starwars/src/main/kotlin/viaduct/demoapp/starwars/config/ViaductConfig.kt" start="1" end="10">}}
```

If no start or end is specified, the whole file is included.

Where path is the path to the source code.

This will show the code in the document and also shows a link to the full file in GitHub.

> There is an optional `lang` parameter to specify the language for syntax highlighting. Default it is `kotlin`.

### Sidebar Nav/Table of Contents

A forked version of `sidebar-tree.html` is used to support non-clickable section headers in the sidebar navigation. To create a non-clickable section header, create a `_index.md` file in the directory with the desired title and set `toc_subsection: true` in the frontmatter. Do not include any content in the file as it will not be rendered.

See `content/docs/developers/_index.md` for an example.

### Development

To run the site locally, you need:

Hugo extended version 0.146+ (see [Hugo installation instructions](https://gohugo.io/getting-started/installing/))

Then, run:

```bash
GOFLAGS=-mod=mod hugo serve
```

Then open `http://localhost:1313` in your browser. If another process is bound to port 1313, hugo picks a random port and it will print the URL in the terminal.

### Deployment

Until we have CI for our site, deployment is manual.

```bash
cd $VIADUCT_REPO
./gradlew :core:tenant:tenant-api:dokkaGenerate
./gradlew :core:service:dokkaGenerate
cd docs
hugo build
VIADUCT_SITE_BUILD=`mktemp -d`
cp -r public/* $VIADUCT_SITE_BUILD
git checkout gh-pages
rm -rf * # Be careful with this command!
mv $VIADUCT_SITE_BUILD/* .
touch .nojekyll
git commit -am 'Publish new site version'
git push origin gh-pages
```

## Dokka

The docs site includes API documentation generated by [Dokka](https://kotlinlang.org/docs/dokka-overview.html) for the Viaduct codebase.

KDocs are split into two: one for tenant developers and one for service/platform developers.

These are generated via Gradle:

```bash
./gradlew :core:tenant:tenant-api:dokkaGenerate
./gradlew :core:service:dokkaGenerate
```

That task outputs HTML files to `docs/static/apis` and from there they are automatically included in the Hugo build.

### Dokka module documentation

https://kotlinlang.org/docs/dokka-module-and-package-docs.html

Create a `module.md` file in the top-level of a module that is opted-in to Dokka. For example, `engine/api/module.md`. See link above for specific Markdown syntax.

### Bring Viaduct code into Docs

Source code snippets can be embedded in the documentation using custom Hugo mounts.

To see, edit, or add new source codes to the documentation, check the file `hugo.yaml` in the root of this repository. It contains Hugo mounts that map source code files from the Viaduct repository into the Hugo site.

There is a section like this

```yaml
  mounts:
    # Mount the Viaduct code for embedding snippets in the docs.
    - source: ../demoapps
      target: assets/demoapps
      includeFiles:
        - "**/*.kt"
        - "**/*.graphqls"
      excludeFiles:
        - "**/build/**"
        - "**/.gradle/**"
        - "**/.idea/**"
        - "**/out/**"
        - "**/.DS_Store"
```

> It is important that the `source` and the target names are the same. In the previous example "demoapps" is used as the source and "demoapps" is used in the target.

Once a source code file is mounted, it can be referenced in the documentation using the `codetag` or `codefile` shortcodes.
