Skip to content

Commit

Permalink
feat: refactor to use gotemplates to render documentation, adds new e…
Browse files Browse the repository at this point in the history
…xample charts

    Fixes #3
  • Loading branch information
norwoodj committed Jul 17, 2019
1 parent ed53371 commit 12e613b
Show file tree
Hide file tree
Showing 29 changed files with 712 additions and 249 deletions.
88 changes: 76 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,82 @@
helm-docs
=========
The helm-docs tool generates automatic documentation from a helm chart into a markdown file. The resulting
file contains metadata about the chart and a table with all of your chart's values, their defaults, and an
The helm-docs tool generates automatic documentation from helm charts into a markdown file. The resulting
file contains metadata about the chart and a table with all of your charts' values, their defaults, and an
optional description parsed from comments.

To build:
The markdown generation is entirely [gotemplate](https://golang.org/pkg/text/template) driven. The tool parses metadata
from charts and generates a number of sub-templates that can be referenced in a template file (by default `README.md.gotmpl`).
If no template file is provided, the tool has a default internal template that will generate a reasonably formatted README.


## Usage
To build from source:
```bash
cd cmd/helm-docs
go build
```

The tool can be invoked on its own, but it must be done in a chart directory containing `values.yaml` and `Chart.yaml`
files.
You can also download the latest release for a variety of platforms from [here](https://github.com/norwoodj/helm-docs/releases/latest).

To run:
```bash
$ helm-docs --dry-run # dry-run prints output to stdout rather than modifying the README in the directory you're in
helm-docs
# OR
helm-docs --dry-run # prints generated documentation to stdout rather than modifying READMEs
```

The tool searches recursively through subdirectories of the current directory for `Chart.yaml` files and generates documentation
for every chart that it finds.


## Available Templates
The templates generated by the tool are shown below, and can be included in your `README.md.gotmpl` file like so:
```
{{ template "template-name" . }}
```

| Name | Description |
|------|-------------|
| chart.header | The main heading of the generated markdown file |
| chart.description | A description line containing the _description_ field from the chart's `Chart.yaml` file, or "" if that field is not set |
| chart.version | The _version_ field from the chart's `Chart.yaml` file |
| chart.versionLine | A text line stating the current version of the chart |
| chart.sourceLink | The _home_ link from the chart's `Chart.yaml` file, or "" if that field is not set |
| chart.sourceLinkLine | A text line with the _home_ link from the chart's `Chart.yaml` file, or "" if that field is not set |
| chart.requirementsHeader | The heading for the chart requirements section |
| chart.requirementsTable | A table of the chart's required sub-charts |
| chart.requirementsSection | A section headed by the requirementsHeader from above containing the requirementsTable from above or "" if there are no requirements |
| chart.valuesHeader | The heading for the chart values section |
| chart.valuesTable | A table of the chart's values parsed from the `values.yaml` file (see below) |
| chart.valuesSection | A section headed by the valuesHeader from above containing the valuesTable from above or "" if there are no values |

For an example of how these various templates can be used in a `README.md.gotmpl` file to generate a reasonable markdown file,
look at the charts in [example-charts](./example-charts).

If there is no `README.md.gotmpl` (or other specified gotmpl file) present, the default template is used to generate the README.
That template looks like so:
```
{{ template "chart.header" . }}
{{ template "chart.description" . }}
{{ template "chart.versionLine" . }}
{{ template "chart.sourceLinkLine" . }}
{{ template "chart.requirementsSection" . }}
{{ template "chart.valuesSection" . }}
```

The tool includes the [spring templating library](https://github.com/Masterminds/sprig), so those functions can be used
in the templates you supply.


## values.yaml metadata
This tool can parse descriptions and defaults of values from values.yaml. The defaults is done automatically by simply
parsing the yaml in the file. Descriptions can be added for parameters by specifying the full path of the value and
a particular format. I invite you to check out the example-chart to see how this is done in practice. In order to add
a description for a parameter you need only put a comment somewhere in the file of the format:
This tool can parse descriptions and defaults of values from `values.yaml` files. The defaults are pulled directly from
the yaml in the file. Descriptions can be added for parameters by specifying the full path of the value and
a particular comment format. I invite you to check out the [example-charts](./example-charts) to see how this is done in
practice. In order to add a description for a parameter you need only put a comment somewhere in the file of the format:

```yaml
controller:
Expand All @@ -33,11 +88,20 @@ controller:
replicas: 2
```
And the descriptions will be picked up and put in the table in the README. The comment need not be near the parameter it
The descriptions will be picked up and put in the table in the README. The comment need not be near the parameter it
explains, although this is probably preferable.
_Note:_ if the value in question contains any `.` characters, that section of the path must be quoted e.g.
```yaml
service:
annotations:
# ingress.annotations."external-dns.alpha.kubernetes.io/hostname" -- Hostname to be assigned to the ELB for the service
external-dns.alpha.kubernetes.io/hostname: stupidchess.jmn23.com
```

### nil values
If you would like to define a key for a value, but leave the default empty, you can still specify a description for it as well as a type. Like so:
If you would like to define a key for a value, but leave the default empty, you can still specify a description for it
as well as a type. Like so:
```yaml
controller:
# controller.replicas -- (int) Number of nginx-ingress pods to load balance between
Expand Down
3 changes: 2 additions & 1 deletion cmd/helm-docs/command_line.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func initializeCli() {
logLevelName := viper.GetString("log-level")
logLevel, err := log.ParseLevel(logLevelName)
if err != nil {
log.Error(err)
log.Errorf("Failed to parse provided log level %s: %s", logLevelName, err)
os.Exit(1)
}

Expand All @@ -44,6 +44,7 @@ func newHelmDocsCommand(run func(cmd *cobra.Command, args []string)) (*cobra.Com

logLevelUsage := fmt.Sprintf("Level of logs that should printed, one of (%s)", strings.Join(possibleLogLevels(), ", "))
command.PersistentFlags().BoolP("dry-run", "d", false, "don't actually render any markdown files just print to stdout passed")
command.PersistentFlags().StringP("template-file", "t", "README.md.gotmpl", "gotemplate file to use to generate documentation for charts")
command.PersistentFlags().StringP("log-level", "l", "info", logLevelUsage)

viper.AutomaticEnv()
Expand Down
5 changes: 3 additions & 2 deletions cmd/helm-docs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ func helmDocs(_ *cobra.Command, _ []string) {
func main() {
command, err := newHelmDocsCommand(helmDocs)
if err != nil {
panic(err)
log.Errorf("Failed to create the CLI commander: %s", err)
os.Exit(1)
}

if err := command.Execute(); err != nil {
log.Error(err)
log.Errorf("Failed to start the CLI: %s", err)
os.Exit(1)
}
}
10 changes: 10 additions & 0 deletions example-charts/custom-template/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: v1
name: custom-template
description: Basically the same as the nginx-ingress chart, but using a custom template to include some other content
version: "18.0901-dev"
home: "https://github.com/norwoodj/helm-docs/example-charts/custom-template"
sources: ["https://github.com/norwoodj/helm-docs/example-charts/custom-template"]
engine: gotpl
maintainers:
- email: norwood.john.m@gmail.com
name: John Norwood
37 changes: 37 additions & 0 deletions example-charts/custom-template/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
custom-template
===============
Basically the same as the nginx-ingress chart, but using a custom template to include some other content

Current chart version is `18.0901-dev`

Source code can be found [here](https://github.com/norwoodj/helm-docs/example-charts/custom-template)

## Additional Information
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.

## Chart Requirements

| Repository | Name | Version |
|------------|------|---------|
| @stable | nginx-ingress | 0.22.1 |

## Chart Values

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| controller.extraVolumes[0].configMap.name | string | "nginx-ingress-config" | Uses the name of the configmap created by this chart |
| controller.extraVolumes[0].name | string | "config-volume" | |
| controller.image.repository | string | "nginx-ingress-controller" | |
| controller.image.tag | string | "18.0831" | |
| controller.ingressClass | string | "nginx" | Name of the ingress class to route through this controller |
| controller.name | string | "controller" | |
| controller.persistentVolumeClaims | list | [] | List of persistent volume claims to create |
| controller.podLabels | object | {} | The labels to be applied to instances of the controller pod |
| controller.publishService.enabled | bool | false | Whether to expose the ingress controller to the public world |
| controller.replicas | int | \<nil\> | Number of nginx-ingress pods to load balance between |
| controller.service.annotations."external-dns.alpha.kubernetes.io/hostname" | string | "stupidchess.jmn23.com" | Hostname to be assigned to the ELB for the service |
| controller.service.type | string | "LoadBalancer" | |
17 changes: 17 additions & 0 deletions example-charts/custom-template/README.md.gotmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{{ template "chart.header" . }}
{{ template "chart.description" . }}

{{ template "chart.versionLine" . }}

{{ template "chart.sourceLinkLine" . }}

## Additional Information
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.

{{ template "chart.requirementsSection" . }}

{{ template "chart.valuesSection" . }}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,11 @@ controller:
enabled: false

# controller.replicas -- (int) Number of nginx-ingress pods to load balance between
replicas:
replicas:

service:
annotations:
# controller.service.annotations."external-dns.alpha.kubernetes.io/hostname" -- Hostname to be assigned to the ELB for the service
external-dns.alpha.kubernetes.io/hostname: stupidchess.jmn23.com

type: LoadBalancer
7 changes: 7 additions & 0 deletions example-charts/most-empty/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v1
name: most-empty
version: "18.0901-dev"
engine: gotpl
maintainers:
- email: norwood.john.m@gmail.com
name: John Norwood
14 changes: 14 additions & 0 deletions example-charts/most-empty/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
most-empty
==========


Current chart version is `18.0901-dev`



This is a good example of all the fields that don't appear when they aren't set in chart metadata. `description`,
`requirements`, and `values` are all empty and don't appear here.




13 changes: 13 additions & 0 deletions example-charts/most-empty/README.md.gotmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{ template "chart.header" . }}
{{ template "chart.description" . }}

{{ template "chart.versionLine" . }}

{{ template "chart.sourceLinkLine" . }}

This is a good example of all the fields that don't appear when they aren't set in chart metadata. `description`,
`requirements`, and `values` are all empty and don't appear here.

{{ template "chart.requirementsSection" . }}

{{ template "chart.valuesSection" . }}
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ apiVersion: v1
name: nginx-ingress
description: A simple wrapper around the stable/nginx-ingress chart that adds a few of our conventions
version: "18.0901-dev"
home: "https://github.com/norwoodj/helm-docs"
sources: ["https://github.com/norwoodj/helm-docs"]
home: "https://github.com/norwoodj/helm-docs/example-charts/nginx-ingress"
sources: ["https://github.com/norwoodj/helm-docs/example-charts/nginx-ingress"]
engine: gotpl
maintainers:
- email: norwood.john.m@gmail.com
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ nginx-ingress
=============
A simple wrapper around the stable/nginx-ingress chart that adds a few of our conventions

This chart's source code can be found [here](https://github.com/norwoodj/helm-docs)
Current chart version is `18.0901-dev`

Source code can be found [here](https://github.com/norwoodj/helm-docs/example-charts/nginx-ingress)

## Chart Requirements

| Repository | Name | Version |
|------------|------|---------|
| @stable | nginx-ingress | 0.22.1 |


## Chart Values

| Key | Type | Default | Description |
Expand All @@ -26,3 +26,5 @@ This chart's source code can be found [here](https://github.com/norwoodj/helm-do
| controller.podLabels | object | {} | The labels to be applied to instances of the controller pod |
| controller.publishService.enabled | bool | false | Whether to expose the ingress controller to the public world |
| controller.replicas | int | \<nil\> | Number of nginx-ingress pods to load balance between |
| controller.service.annotations."external-dns.alpha.kubernetes.io/hostname" | string | "stupidchess.jmn23.com" | Hostname to be assigned to the ELB for the service |
| controller.service.type | string | "LoadBalancer" | |
4 changes: 4 additions & 0 deletions example-charts/nginx-ingress/requirements.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dependencies:
- name: nginx-ingress
version: "0.22.1"
repository: "@stable"
34 changes: 34 additions & 0 deletions example-charts/nginx-ingress/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
controller:
name: controller
image:
repository: nginx-ingress-controller
tag: "18.0831"

# controller.persistentVolumeClaims -- List of persistent volume claims to create
persistentVolumeClaims: []

extraVolumes:
- name: config-volume
configMap:
# controller.extraVolumes[0].configMap.name -- Uses the name of the configmap created by this chart
name: nginx-ingress-config

# controller.ingressClass -- Name of the ingress class to route through this controller
ingressClass: nginx

# controller.podLabels -- The labels to be applied to instances of the controller pod
podLabels: {}

publishService:
# controller.publishService.enabled -- Whether to expose the ingress controller to the public world
enabled: false

# controller.replicas -- (int) Number of nginx-ingress pods to load balance between
replicas:

service:
annotations:
# controller.service.annotations."external-dns.alpha.kubernetes.io/hostname" -- Hostname to be assigned to the ELB for the service
external-dns.alpha.kubernetes.io/hostname: stupidchess.jmn23.com

type: LoadBalancer
10 changes: 10 additions & 0 deletions example-charts/no-requirements/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: v1
name: no-requirements
description: A simple chart that installs, let's say PrometheusRules, that needs no sub-charts
version: "18.0901-dev"
home: "https://github.com/norwoodj/helm-docs/example-charts/no-requirements"
sources: ["https://github.com/norwoodj/helm-docs/example-charts/no-requirements"]
engine: gotpl
maintainers:
- email: norwood.john.m@gmail.com
name: John Norwood
18 changes: 18 additions & 0 deletions example-charts/no-requirements/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
no-requirements
===============
A simple chart that installs, let's say PrometheusRules, that needs no sub-charts

Current chart version is `18.0901-dev`

Source code can be found [here](https://github.com/norwoodj/helm-docs/example-charts/no-requirements)



## Chart Values

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| rules.latency.percentiles.99.duration | string | "5m" | Duration for which the 99th percentile must be above the threshold to alert |
| rules.latency.percentiles.99.threshold | float | 1.5 | Threshold in seconds for our 99th percentile latency above which the alert will fire |
| rules.statusCodes.codes.5xx.duration | string | "5m" | Duration for which the percent of 5xx responses must be above the threshold to alert |
| rules.statusCodes.codes.5xx.threshold | float | 1.5 | Threshold percentage of 5xx responses above which the alert will fire |
16 changes: 16 additions & 0 deletions example-charts/no-requirements/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
rules:
latency:
percentiles:
"99":
# rules.latency.percentiles.99.threshold -- Threshold in seconds for our 99th percentile latency above which the alert will fire
threshold: 1.5
# rules.latency.percentiles.99.duration -- Duration for which the 99th percentile must be above the threshold to alert
duration: 5m

statusCodes:
codes:
5xx:
# rules.statusCodes.codes.5xx.threshold -- Threshold percentage of 5xx responses above which the alert will fire
threshold: 1.5
# rules.statusCodes.codes.5xx.duration -- Duration for which the percent of 5xx responses must be above the threshold to alert
duration: 5m
10 changes: 10 additions & 0 deletions example-charts/no-values/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: v1
name: no-values
description: A very simple chart that doesn't even need any values for customization
version: "18.0901-dev"
home: "https://github.com/norwoodj/helm-docs/example-charts/no-values"
sources: ["https://github.com/norwoodj/helm-docs/example-charts/no-values"]
engine: gotpl
maintainers:
- email: norwood.john.m@gmail.com
name: John Norwood
Loading

0 comments on commit 12e613b

Please sign in to comment.