Skip to content

Commit

Permalink
feat: updates values table generation allowing for non-empty lists/ma…
Browse files Browse the repository at this point in the history
…ps to be documented

  Fixes #9
  • Loading branch information
norwoodj committed Jul 29, 2019
1 parent 5d75e92 commit bf2cedc
Show file tree
Hide file tree
Showing 13 changed files with 876 additions and 158 deletions.
15 changes: 15 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
helm-docs:
cd cmd/helm-docs && go build
mv cmd/helm-docs/helm-docs .

.PHONY: fmt
fmt:
go fmt ./...

.PHONY: test
test:
go test -v ./...

.PHONY: clean
clean:
rm helm-docs
13 changes: 10 additions & 3 deletions cmd/helm-docs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/spf13/viper"
)

func retrieveInfoAndPrintDocumentation(chartDirectory string, waitGroup *sync.WaitGroup) {
func retrieveInfoAndPrintDocumentation(chartDirectory string, waitGroup *sync.WaitGroup, dryRun bool) {
defer waitGroup.Done()
chartDocumentationInfo, err := helm.ParseChartInformation(chartDirectory)

Expand All @@ -21,7 +21,7 @@ func retrieveInfoAndPrintDocumentation(chartDirectory string, waitGroup *sync.Wa
return
}

document.PrintDocumentation(chartDocumentationInfo, viper.GetBool("dry-run"))
document.PrintDocumentation(chartDocumentationInfo, dryRun)

}

Expand All @@ -35,11 +35,18 @@ func helmDocs(_ *cobra.Command, _ []string) {
}

log.Infof("Found Chart directories [%s]", strings.Join(chartDirs, ", "))
dryRun := viper.GetBool("dry-run")
waitGroup := sync.WaitGroup{}

for _, c := range chartDirs {
waitGroup.Add(1)
go retrieveInfoAndPrintDocumentation(c, &waitGroup)

// On dry runs all output goes to stdout, and so as to not jumble things, generate serially
if dryRun {
retrieveInfoAndPrintDocumentation(c, &waitGroup, dryRun)
} else {
go retrieveInfoAndPrintDocumentation(c, &waitGroup, dryRun)
}
}

waitGroup.Wait()
Expand Down
22 changes: 11 additions & 11 deletions example-charts/custom-template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ culpa qui officia deserunt mollit anim id est laborum.

| 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.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" | |
| 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"` | |
23 changes: 12 additions & 11 deletions example-charts/nginx-ingress/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@ Source code can be found [here](https://github.com/norwoodj/helm-docs/example-ch

| 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.extraVolumes | list | `[{"configMap":{"name":"nginx-ingress-config"},"name":"config-volume"}]` | Additional volumes to be mounted into the ingress controller container |
| 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.livenessProbe | object | `{"httpGet":{"path":"/healthz","port":8080}}` | Configure the healthcheck for the ingress controller |
| controller.livenessProbe.httpGet.path | string | `"/healthz"` | This is the liveness check endpoint |
| 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" | |
| 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"` | |
9 changes: 8 additions & 1 deletion example-charts/nginx-ingress/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,19 @@ controller:
# controller.persistentVolumeClaims -- List of persistent volume claims to create
persistentVolumeClaims: []

# controller.extraVolumes -- Additional volumes to be mounted into the ingress controller container
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.livenessProbe -- Configure the healthcheck for the ingress controller
livenessProbe:
httpGet:
# controller.livenessProbe.httpGet.path -- This is the liveness check endpoint
path: /healthz
port: 8080

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

Expand Down
8 changes: 4 additions & 4 deletions example-charts/no-requirements/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Source code can be found [here](https://github.com/norwoodj/helm-docs/example-ch

| 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 |
| 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 |
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ require (
github.com/spf13/cobra v0.0.5
github.com/spf13/pflag v1.0.3
github.com/spf13/viper v1.4.0
github.com/stretchr/testify v1.2.2
gopkg.in/yaml.v2 v2.2.2
)
25 changes: 14 additions & 11 deletions pkg/document/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ package document

import (
"fmt"
"os"
"path/filepath"

"github.com/norwoodj/helm-docs/pkg/helm"
log "github.com/sirupsen/logrus"
"os"
"path/filepath"
)

func getOutputFile(chartDirectory string, dryRun bool) (*os.File, error) {
Expand All @@ -26,25 +25,29 @@ func getOutputFile(chartDirectory string, dryRun bool) (*os.File, error) {
func PrintDocumentation(chartDocumentationInfo helm.ChartDocumentationInfo, dryRun bool) {
log.Infof("Generating README Documentation for chart %s", chartDocumentationInfo.ChartDirectory)

outputFile, err := getOutputFile(chartDocumentationInfo.ChartDirectory, dryRun)
chartDocumentationTemplate, err := newChartDocumentationTemplate(chartDocumentationInfo)
if err != nil {
log.Warnf("Could not open chart README file %s, skipping chart", filepath.Join(chartDocumentationInfo.ChartDirectory, "README.md"))
log.Warnf("Error generating gotemplates for chart %s: %s", chartDocumentationInfo.ChartDirectory, err)
return
}

if !dryRun {
defer outputFile.Close()
chartTemplateDataObject, err := getChartTemplateData(chartDocumentationInfo)
if err != nil {
log.Warnf("Error generating template data for chart %s: %s", chartDocumentationInfo.ChartDirectory, err)
return
}

chartDocumentationTemplate, err := newChartDocumentationTemplate(chartDocumentationInfo)
outputFile, err := getOutputFile(chartDocumentationInfo.ChartDirectory, dryRun)
if err != nil {
log.Warnf("Error generating templates for chart %s: %s", chartDocumentationInfo.ChartDirectory, err)
log.Warnf("Could not open chart README file %s, skipping chart", filepath.Join(chartDocumentationInfo.ChartDirectory, "README.md"))
return
}

chartTemplateDataObject := getChartTemplateData(chartDocumentationInfo)
err = chartDocumentationTemplate.Execute(outputFile, chartTemplateDataObject)
if !dryRun {
defer outputFile.Close()
}

err = chartDocumentationTemplate.Execute(outputFile, chartTemplateDataObject)
if err != nil {
log.Warnf("Error generating documentation for chart %s: %s", chartDocumentationInfo.ChartDirectory, err)
}
Expand Down
15 changes: 12 additions & 3 deletions pkg/document/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,20 @@ type chartTemplateData struct {
Values []valueRow
}

func getChartTemplateData(chartDocumentationInfo helm.ChartDocumentationInfo) chartTemplateData {
valuesTableRows := createValueRows("", chartDocumentationInfo.ChartValues, chartDocumentationInfo.ChartValuesDescriptions)
func getChartTemplateData(chartDocumentationInfo helm.ChartDocumentationInfo) (chartTemplateData, error) {
valuesTableRows, err := createValueRowsFromObject(
"",
chartDocumentationInfo.ChartValues,
chartDocumentationInfo.ChartValuesDescriptions,
true,
)

if err != nil {
return chartTemplateData{}, err
}

return chartTemplateData{
ChartDocumentationInfo: chartDocumentationInfo,
Values: valuesTableRows,
}
}, nil
}
49 changes: 49 additions & 0 deletions pkg/document/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package document

import (
"fmt"
)

type jsonableMap map[string]interface{}

func convertMapKeyToString(key interface{}) string {
switch key.(type) {
case string:
return key.(string)
case int:
return fmt.Sprintf("int(%d)", key)
case float64:
return fmt.Sprintf("float(%f)", key)
case bool:
return fmt.Sprintf("bool(%t)", key)
}

return fmt.Sprintf("?(%+v)", key)
}

// The json library can only marshal maps with string keys, and so all of our lists and maps that go into documentation
// must be converted to have only string keys before marshalling
func convertHelmValuesToJsonable(values interface{}) interface{} {
switch values.(type) {
case map[interface{}]interface{}:
convertedMap := make(jsonableMap)

for key, value := range values.(map[interface{}]interface{}) {
convertedMap[convertMapKeyToString(key)] = convertHelmValuesToJsonable(value)
}

return convertedMap

case []interface{}:
convertedList := make([]interface{}, 0)

for _, value := range values.([]interface{}) {
convertedList = append(convertedList, convertHelmValuesToJsonable(value))
}

return convertedList

default:
return values
}
}
Loading

0 comments on commit bf2cedc

Please sign in to comment.