Skip to content

Commit

Permalink
Merge pull request #112 from armsnyder/umbrella-values
Browse files Browse the repository at this point in the history
New flag --document-dependency-values
  • Loading branch information
norwoodj committed Apr 25, 2022
2 parents 435f142 + fa4d751 commit 902641c
Show file tree
Hide file tree
Showing 22 changed files with 538 additions and 85 deletions.
1 change: 1 addition & 0 deletions cmd/helm-docs/command_line.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func newHelmDocsCommand(run func(cmd *cobra.Command, args []string)) (*cobra.Com
command.PersistentFlags().StringSliceP("template-files", "t", []string{"README.md.gotmpl"}, "gotemplate file paths relative to each chart directory from which documentation will be generated")
command.PersistentFlags().StringP("badge-style", "b", "flat-square", "badge style to use for charts")
command.PersistentFlags().StringP("values-file", "f", "values.yaml", "Path to values file")
command.PersistentFlags().BoolP("document-dependency-values", "u", false, "For charts with dependencies, include the dependency values in the chart values documentation")

viper.AutomaticEnv()
viper.SetEnvPrefix("HELM_DOCS")
Expand Down
118 changes: 91 additions & 27 deletions cmd/helm-docs/main.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package main

import (
"fmt"
"os"
"path"
"path/filepath"
"reflect"
"runtime"
"strings"
"sync"

Expand All @@ -14,65 +18,125 @@ import (
"github.com/norwoodj/helm-docs/pkg/helm"
)

func retrieveInfoAndPrintDocumentation(chartDirectory string, chartSearchRoot string, templateFiles []string, waitGroup *sync.WaitGroup, badgeStyle string, dryRun bool) {
defer waitGroup.Done()
chartDocumentationInfo, err := helm.ParseChartInformation(path.Join(chartSearchRoot, chartDirectory))

if err != nil {
log.Warnf("Error parsing information for chart %s, skipping: %s", chartDirectory, err)
return
// parallelProcessIterable runs the visitFn function on each element of the iterable, using
// parallelism number of worker goroutines. The iterable may be a slice or a map. In the case of a
// map, the argument passed to visitFn will be the key.
func parallelProcessIterable(iterable interface{}, parallelism int, visitFn func(elem interface{})) {
workChan := make(chan interface{})

wg := &sync.WaitGroup{}
wg.Add(parallelism)

for i := 0; i < parallelism; i++ {
go func() {
defer wg.Done()
for elem := range workChan {
visitFn(elem)
}
}()
}

document.PrintDocumentation(chartDocumentationInfo, chartSearchRoot, templateFiles, dryRun, version, badgeStyle)
iterableValue := reflect.ValueOf(iterable)

}
if iterableValue.Kind() == reflect.Map {
for _, key := range iterableValue.MapKeys() {
workChan <- key.Interface()
}
} else {
sliceLen := iterableValue.Len()
for i := 0; i < sliceLen; i++ {
workChan <- iterableValue.Index(i).Interface()
}
}

func helmDocs(_ *cobra.Command, _ []string) {
initializeCli()
close(workChan)
wg.Wait()
}

chartSearchRoot := viper.GetString("chart-search-root")
func readDocumentationInfoByChartPath(chartSearchRoot string, parallelism int) (map[string]helm.ChartDocumentationInfo, error) {
var fullChartSearchRoot string

if path.IsAbs(chartSearchRoot) {
fullChartSearchRoot = chartSearchRoot
} else {
cwd, err := os.Getwd()
if err != nil {
log.Warnf("Error getting working directory: %s", err)
return
return nil, fmt.Errorf("error getting working directory: %w", err)
}

fullChartSearchRoot = path.Join(cwd, chartSearchRoot)
fullChartSearchRoot = filepath.Join(cwd, chartSearchRoot)
}

chartDirs, err := helm.FindChartDirectories(fullChartSearchRoot)
if err != nil {
log.Errorf("Error finding chart directories: %s", err)
os.Exit(1)
return nil, fmt.Errorf("error finding chart directories: %w", err)
}

log.Infof("Found Chart directories [%s]", strings.Join(chartDirs, ", "))

templateFiles := viper.GetStringSlice("template-files")
log.Debugf("Rendering from optional template files [%s]", strings.Join(templateFiles, ", "))

documentationInfoByChartPath := make(map[string]helm.ChartDocumentationInfo, len(chartDirs))
documentationInfoByChartPathMu := &sync.Mutex{}

parallelProcessIterable(chartDirs, parallelism, func(elem interface{}) {
chartDir := elem.(string)
info, err := helm.ParseChartInformation(filepath.Join(chartSearchRoot, chartDir))
if err != nil {
log.Warnf("Error parsing information for chart %s, skipping: %s", chartDir, err)
return
}
documentationInfoByChartPathMu.Lock()
documentationInfoByChartPath[info.ChartDirectory] = info
documentationInfoByChartPathMu.Unlock()
})

return documentationInfoByChartPath, nil
}

func writeDocumentation(chartSearchRoot string, documentationInfoByChartPath map[string]helm.ChartDocumentationInfo, dryRun bool, parallelism int) {
templateFiles := viper.GetStringSlice("template-files")
badgeStyle := viper.GetString("badge-style")

log.Debugf("Rendering from optional template files [%s]", strings.Join(templateFiles, ", "))

documentDependencyValues := viper.GetBool("document-dependency-values")

parallelProcessIterable(documentationInfoByChartPath, parallelism, func(elem interface{}) {
info := documentationInfoByChartPath[elem.(string)]
var err error
var dependencyValues []document.DependencyValues
if documentDependencyValues {
dependencyValues, err = document.GetDependencyValues(info, documentationInfoByChartPath)
if err != nil {
log.Warnf("Error evaluating dependency values for chart %s, skipping: %v", info.ChartDirectory, err)
return
}
}
document.PrintDocumentation(info, chartSearchRoot, templateFiles, dryRun, version, badgeStyle, dependencyValues)
})
}

func helmDocs(_ *cobra.Command, _ []string) {
initializeCli()

chartSearchRoot := viper.GetString("chart-search-root")
dryRun := viper.GetBool("dry-run")
waitGroup := sync.WaitGroup{}

for _, c := range chartDirs {
waitGroup.Add(1)
parallelism := runtime.NumCPU() * 2

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

documentationInfoByChartPath, err := readDocumentationInfoByChartPath(chartSearchRoot, parallelism)
if err != nil {
log.Fatal(err)
}

waitGroup.Wait()
writeDocumentation(chartSearchRoot, documentationInfoByChartPath, dryRun, parallelism)
}

func main() {
Expand Down
14 changes: 14 additions & 0 deletions example-charts/umbrella/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: v2
name: umbrella
description: A chart demonstrating that values documentation from child charts are aggregated on the parent chart.
version: "0.1.0"
type: application
dependencies:
- name: sub-a
version: 0.1.0
- name: sub-b
version: 0.1.0
- name: sub-c
version: 0.1.0
- name: library
version: 0.1.0
26 changes: 26 additions & 0 deletions example-charts/umbrella/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# umbrella

![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)

A chart demonstrating that values documentation from child charts are aggregated on the parent chart.

## Requirements

| Repository | Name | Version |
|------------|------|---------|
| | library | 0.1.0 |
| | sub-a | 0.1.0 |
| | sub-b | 0.1.0 |
| | sub-c | 0.1.0 |

## Values

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| global | object | `{}` | |
| global.myGlobalKey | string | `"my-global-value"` | A global key |
| global.myGlobalSubChartKey | string | `"my-global-sub-chart-value"` | A global key defined in a sub chart |
| myParentKey | string | `"my-parent-value"` | A parent key |
| sub-a.mySubKeyA | string | `"my-sub-value-a"` | Value for sub-chart A |
| sub-b.mySubKeyB | string | `"my-sub-value-b"` | Value for sub-chart B |

5 changes: 5 additions & 0 deletions example-charts/umbrella/charts/library/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apiVersion: v2
name: library
description: An example library sub-chart with no values.
version: "0.1.0"
type: library
9 changes: 9 additions & 0 deletions example-charts/umbrella/charts/sub-a/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: v2
name: sub-a
description: A sub-chart.
version: "0.1.0"
type: application
dependencies:
- name: library
version: 0.1.0
repository: file://../library
20 changes: 20 additions & 0 deletions example-charts/umbrella/charts/sub-a/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# sub-a

![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)

A sub-chart.

## Requirements

| Repository | Name | Version |
|------------|------|---------|
| file://../library | library | 0.1.0 |

## Values

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| global.myGlobalKey | string | `"my-global-value"` | A global key |
| global.myGlobalSubChartKey | string | `"my-global-sub-chart-value"` | A global key defined in a sub chart |
| mySubKeyA | string | `"my-sub-value-a"` | Value for sub-chart A |

9 changes: 9 additions & 0 deletions example-charts/umbrella/charts/sub-a/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
global:
# -- A global key
myGlobalKey: my-global-value

# -- A global key defined in a sub chart
myGlobalSubChartKey: my-global-sub-chart-value

# -- Value for sub-chart A
mySubKeyA: my-sub-value-a
9 changes: 9 additions & 0 deletions example-charts/umbrella/charts/sub-b/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: v2
name: sub-b
description: A sub-chart.
version: "0.1.0"
type: application
dependencies:
- name: library
version: 0.1.0
repository: file://../library
19 changes: 19 additions & 0 deletions example-charts/umbrella/charts/sub-b/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# sub-b

![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)

A sub-chart.

## Requirements

| Repository | Name | Version |
|------------|------|---------|
| file://../library | library | 0.1.0 |

## Values

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| global.myGlobalKey | string | `"my-global-value"` | A global key |
| mySubKeyB | string | `"my-sub-value-b"` | Value for sub-chart B |

6 changes: 6 additions & 0 deletions example-charts/umbrella/charts/sub-b/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
global:
# -- A global key
myGlobalKey: my-global-value

# -- Value for sub-chart B
mySubKeyB: my-sub-value-b
9 changes: 9 additions & 0 deletions example-charts/umbrella/charts/sub-c/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: v2
name: sub-c
description: A sub-chart.
version: "0.1.0"
type: application
dependencies:
- name: library
version: 0.1.0
repository: file://../library
18 changes: 18 additions & 0 deletions example-charts/umbrella/charts/sub-c/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# sub-c

![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)

A sub-chart.

## Requirements

| Repository | Name | Version |
|------------|------|---------|
| file://../library | library | 0.1.0 |

## Values

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| global | object | `{}` | |

1 change: 1 addition & 0 deletions example-charts/umbrella/charts/sub-c/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
global: {}
6 changes: 6 additions & 0 deletions example-charts/umbrella/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
global:
# -- A global key
myGlobalKey: my-global-value

# -- A parent key
myParentKey: my-parent-value

0 comments on commit 902641c

Please sign in to comment.