Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Support for subsectioned Values #194

Merged
merged 9 commits into from
Dec 21, 2023
19 changes: 19 additions & 0 deletions example-charts/sections/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: v2
name: sections
deprecated: true
version: "1.0.0"
type: application
appVersion: "13.0.0"
description: A chart for showing how to use sections
home: "https://github.com/norwoodj/helm-docs/tree/master/example-charts/sections"
maintainers:
- email: [email protected]
name: Constantin Rohde
sources: ["https://github.com/norwoodj/helm-docs/tree/master/example-charts/sections"]
kubeVersion: "<=1.18"
engine: gotpl

dependencies:
- name: nginx-ingress
version: "0.22.1"
repository: "@stable"
173 changes: 173 additions & 0 deletions example-charts/sections/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# Sections

## Values

### General
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| controller.extraVolumes[0].name | string | `"config-volume"` | |
| controller.image.repository | string | `"nginx-ingress-controller"` | |
| controller.image.tag | string | `"18.0831"` | |
| controller.name | string | `"controller"` | |
| 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"` | |

### Some Section
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| controller.extraVolumes[0].configMap.name | string | `"nginx-ingress-config"` | Uses the name of the configmap created by this chart |
| controller.persistentVolumeClaims | list | the chart will construct this list internally unless specified | List of persistent volume claims to create. |
| controller.podLabels | object | `{}` | The labels to be applied to instances of the controller pod |

### Special Attention
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| controller.ingressClass | string | `"nginx"` | You can also specify value comments like this |
| controller.publishService | object | `{"enabled":false}` | This is a publishService |
| controller.replicas | int | `nil` | Number of nginx-ingress pods to load balance between |

## Values

<h3>General</h3>
<table>
<thead>
<th>Key</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</thead>
<tbody>
<tr>
<td>controller.extraVolumes[0].name</td>
<td>string</td>
<td><pre lang="json">
"config-volume"
</pre>
</td>
<td></td>
</tr>
<tr>
<td>controller.image.repository</td>
<td>string</td>
<td><pre lang="json">
"nginx-ingress-controller"
</pre>
</td>
<td></td>
</tr>
<tr>
<td>controller.image.tag</td>
<td>string</td>
<td><pre lang="json">
"18.0831"
</pre>
</td>
<td></td>
</tr>
<tr>
<td>controller.name</td>
<td>string</td>
<td><pre lang="json">
"controller"
</pre>
</td>
<td></td>
</tr>
<tr>
<td>controller.service.annotations."external-dns.alpha.kubernetes.io/hostname"</td>
<td>string</td>
<td><pre lang="json">
"stupidchess.jmn23.com"
</pre>
</td>
<td>Hostname to be assigned to the ELB for the service</td>
</tr>
<tr>
<td>controller.service.type</td>
<td>string</td>
<td><pre lang="json">
"LoadBalancer"
</pre>
</td>
<td></td>
</tr>
</tbody>
</table>
<h3>Some Section</h3>
<table>
<thead>
<th>Key</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</thead>
<tbody>
<tr>
<td>controller.extraVolumes[0].configMap.name</td>
<td>string</td>
<td><pre lang="json">
"nginx-ingress-config"
</pre>
</td>
<td>Uses the name of the configmap created by this chart</td>
</tr>
<tr>
<td>controller.persistentVolumeClaims</td>
<td>list</td>
<td><pre lang="">
the chart will construct this list internally unless specified
</pre>
</td>
<td>List of persistent volume claims to create.</td>
</tr>
<tr>
<td>controller.podLabels</td>
<td>object</td>
<td><pre lang="json">
{}
</pre>
</td>
<td>The labels to be applied to instances of the controller pod</td>
</tr>
</tbody>
</table>
<h3>Special Attention</h3>
<table>
<thead>
<th>Key</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</thead>
<tbody>
<tr>
<td>controller.ingressClass</td>
<td>string</td>
<td><pre lang="json">
"nginx"
</pre>
</td>
<td>You can also specify value comments like this</td>
</tr>
<tr>
<td>controller.publishService</td>
<td>object</td>
<td><pre lang="json">
{
"enabled": false
}
</pre>
</td>
<td>This is a publishService</td>
</tr>
<tr>
<td>controller.replicas</td>
<td>int</td>
<td><pre lang="json">
null
</pre>
</td>
<td>Number of nginx-ingress pods to load balance between</td>
</tr>
</tbody>
</table>
5 changes: 5 additions & 0 deletions example-charts/sections/README.md.gotmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Sections

{{ template "chart.valuesSectionedSection" . }}

{{ template "chart.valuesSectionedSectionHtml" . }}
43 changes: 43 additions & 0 deletions example-charts/sections/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
controller:
name: controller
image:
repository: nginx-ingress-controller
tag: "18.0831"

# controller.persistentVolumeClaims -- List of persistent volume claims to create.
# @default -- the chart will construct this list internally unless specified
# @section -- Some Section
persistentVolumeClaims: []

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

# -- You can also specify value comments like this
# @section -- Special Attention
ingressClass: nginx


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

# controller.publishService -- This is a publishService
# @section -- Special Attention
publishService:
enabled: false

# -- (int) Number of nginx-ingress pods to load balance between
# @raw
# @section -- Special Attention
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
87 changes: 87 additions & 0 deletions pkg/document/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type valueRow struct {
Default string
AutoDescription string
Description string
Section string
Column int
LineNumber int
Dependency string
Expand All @@ -30,9 +31,15 @@ type chartTemplateData struct {
helm.ChartDocumentationInfo
HelmDocsVersion string
Values []valueRow
Sections []section
Files files
}

type section struct {
SectionName string
SectionItems []valueRow
}

func sortValueRows(valueRows []valueRow) {
sortOrder := viper.GetString("sort-values-order")

Expand Down Expand Up @@ -75,6 +82,50 @@ func sortValueRows(valueRows []valueRow) {
})
}

func sortSectionedValueRows(sectionedValueRows []section) {
sortOrder := viper.GetString("sort-values-order")

if sortOrder != FileSortOrder && sortOrder != AlphaNumSortOrder {
log.Warnf("Invalid sort order provided %s, defaulting to %s", sortOrder, AlphaNumSortOrder)
sortOrder = AlphaNumSortOrder
}

for _, section := range sectionedValueRows {
sort.Slice(section.SectionItems, func(i, j int) bool {
// Globals sort above non-globals.
if section.SectionItems[i].IsGlobal != section.SectionItems[j].IsGlobal {
return section.SectionItems[i].IsGlobal
}

// Group by dependency for non-globals.
if !section.SectionItems[i].IsGlobal && !section.SectionItems[j].IsGlobal {
// Values for the main chart sort above values for dependencies.
if (section.SectionItems[i].Dependency == "") != (section.SectionItems[j].Dependency == "") {
return section.SectionItems[i].Dependency == ""
}

// Group dependency values together.
if section.SectionItems[i].Dependency != section.SectionItems[j].Dependency {
return section.SectionItems[i].Dependency < section.SectionItems[j].Dependency
}
}

// Sort the remaining values within the same section.SectionItems using the configured sort order.
switch sortOrder {
case FileSortOrder:
if section.SectionItems[i].LineNumber == section.SectionItems[j].LineNumber {
return section.SectionItems[i].Column < section.SectionItems[j].Column
}
return section.SectionItems[i].LineNumber < section.SectionItems[j].LineNumber
case AlphaNumSortOrder:
return section.SectionItems[i].Key < section.SectionItems[j].Key
default:
panic("cannot get here")
}
})
}
}

func getUnsortedValueRows(document *yaml.Node, descriptions map[string]helm.ChartValueDescription) ([]valueRow, error) {
// Handle empty values file case.
if document.Kind == 0 {
Expand All @@ -92,6 +143,39 @@ func getUnsortedValueRows(document *yaml.Node, descriptions map[string]helm.Char
return createValueRowsFromField("", nil, document.Content[0], descriptions, true)
}

func getUnsortedSectionedValueRows(valueRows []valueRow) []section {
var valueRowsSectionSorted []section
valueRowsSectionSorted = append(valueRowsSectionSorted, section{
SectionName: "General",
SectionItems: []valueRow{},
})

for _, row := range valueRows {
if row.Section == "" {
valueRowsSectionSorted[0].SectionItems = append(valueRowsSectionSorted[0].SectionItems, row)
continue
}

containsSection := false
for i, section := range valueRowsSectionSorted {
if section.SectionName == row.Section {
containsSection = true
valueRowsSectionSorted[i].SectionItems = append(valueRowsSectionSorted[i].SectionItems, row)
break
}
}

if !containsSection {
valueRowsSectionSorted = append(valueRowsSectionSorted, section{
SectionName: row.Section,
SectionItems: []valueRow{row},
})
}
}

return valueRowsSectionSorted
}

func getChartTemplateData(info helm.ChartDocumentationInfo, helmDocsVersion string, dependencyValues []DependencyValues) (chartTemplateData, error) {
valuesTableRows, err := getUnsortedValueRows(info.ChartValues, info.ChartValuesDescriptions)
if err != nil {
Expand Down Expand Up @@ -135,6 +219,8 @@ func getChartTemplateData(info helm.ChartDocumentationInfo, helmDocsVersion stri
}

sortValueRows(valuesTableRows)
valueRowsSectionSorted := getUnsortedSectionedValueRows(valuesTableRows)
sortSectionedValueRows(valueRowsSectionSorted)

files, err := getFiles(info.ChartDirectory)
if err != nil {
Expand All @@ -145,6 +231,7 @@ func getChartTemplateData(info helm.ChartDocumentationInfo, helmDocsVersion stri
ChartDocumentationInfo: info,
HelmDocsVersion: helmDocsVersion,
Values: valuesTableRows,
Sections: valueRowsSectionSorted,
Files: files,
}, nil
}
Expand Down
Loading