Skip to content

Commit

Permalink
Merge pull request #24 from dadav/feat_parse_comments
Browse files Browse the repository at this point in the history
feat: Add possibility to parse comments
  • Loading branch information
dadav authored Apr 17, 2024
2 parents 8a49439 + 1fd5016 commit d6e8314
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ Flags:
-o, --output-file string "jsonschema file path relative to each chart directory to which jsonschema will be written (default 'values.schema.json')"
-f, --value-files strings "filenames to check for chart values (default [values.yaml])"
-k, --skip-auto-generation strings "skip the auto generation for these fields (default [])"
-u, --uncomment "Consinder yaml which is commented out"
-v, --version "version for helm-schema"
```

Expand Down
2 changes: 2 additions & 0 deletions cmd/helm-schema/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ func newCommand(run func(cmd *cobra.Command, args []string) error) (*cobra.Comma
BoolP("dry-run", "d", false, "don't actually create files just print to stdout passed")
cmd.PersistentFlags().
BoolP("keep-full-comment", "s", false, "Keep the whole leading comment (default: cut at empty line)")
cmd.PersistentFlags().
BoolP("uncomment", "u", false, "Consinder yaml which is commented out")
cmd.PersistentFlags().
BoolP("dont-strip-helm-docs-prefix", "x", false, "Disable the removal of the helm-docs prefix (--)")
cmd.PersistentFlags().
Expand Down
16 changes: 15 additions & 1 deletion cmd/helm-schema/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"bytes"
"errors"
"fmt"
"os"
Expand Down Expand Up @@ -47,7 +48,7 @@ type Result struct {
}

func worker(
dryRun, keepFullComment, dontRemoveHelmDocsPrefix bool,
dryRun, uncomment, keepFullComment, dontRemoveHelmDocsPrefix bool,
valueFileNames []string,
skipAutoGenerationConfig *schema.SkipAutoGenerationConfig,
outFile string,
Expand Down Expand Up @@ -113,6 +114,17 @@ func worker(
continue
}

// Optional preprocessing
if uncomment {
// Remove comments from valid yaml
content, err = util.RemoveCommentsFromYaml(bytes.NewReader(content))
if err != nil {
result.Errors = append(result.Errors, err)
results <- result
continue
}
}

var values yaml.Node
err = yaml.Unmarshal(content, &values)
if err != nil {
Expand All @@ -136,6 +148,7 @@ func exec(cmd *cobra.Command, _ []string) error {
dryRun := viper.GetBool("dry-run")
noDeps := viper.GetBool("no-dependencies")
keepFullComment := viper.GetBool("keep-full-comment")
uncomment := viper.GetBool("uncomment")
outFile := viper.GetString("output-file")
dontRemoveHelmDocsPrefix := viper.GetBool("dont-strip-helm-docs-prefix")
if err := viper.UnmarshalKey("value-files", &valueFileNames); err != nil {
Expand Down Expand Up @@ -174,6 +187,7 @@ func exec(cmd *cobra.Command, _ []string) error {
defer wg.Done()
worker(
dryRun,
uncomment,
keepFullComment,
dontRemoveHelmDocsPrefix,
valueFileNames,
Expand Down
104 changes: 103 additions & 1 deletion pkg/util/file.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package util

import (
"bufio"
"io"
"regexp"
"strings"

"gopkg.in/yaml.v3"
)

// ReadFileAndFixNewline reads the content of a io.Reader and replaces \r\n with \n
Expand All @@ -11,5 +15,103 @@ func ReadFileAndFixNewline(reader io.Reader) ([]byte, error) {
if err != nil {
return nil, err
}
return []byte(strings.Replace(string(content), "\r\n", "\n", -1)), nil
return []byte(strings.ReplaceAll(string(content), "\r\n", "\n")), nil
}

func appendAndNL(to, from *[]byte) {
if from != nil {
*to = append(*to, *from...)
}
*to = append(*to, '\n')
}

func appendAndNLStr(to *[]byte, from string) {
*to = append(*to, from...)
*to = append(*to, '\n')
}

// RemoveCommentsFromYaml tries to remove comments if they contain valid yaml
func RemoveCommentsFromYaml(reader io.Reader) ([]byte, error) {
result := make([]byte, 0)
buff := make([]byte, 0)
scanner := bufio.NewScanner(reader)

commentMatcher := regexp.MustCompile(`^\s*#\s*`)
schemaMatcher := regexp.MustCompile(`^\s*#\s@schema\s*`)

var line string
var inCode, inSchema bool
var codeIndention int
var unknownYaml interface{}

for scanner.Scan() {
line = scanner.Text()

// If the line is empty and we are parsing a block of potential yaml,
// the parsed block of yaml is "finished" and should be added to the
// result
if line == "" && inCode {
appendAndNL(&result, &buff)
appendAndNLStr(&result, line)
// reset
inCode = false
buff = make([]byte, 0)
continue
}

// Line contains @schema
// The following lines will be added to result
if schemaMatcher.Match([]byte(line)) {
inSchema = !inSchema
appendAndNLStr(&result, line)
continue
}

// Inside a @schema block
if inSchema {
appendAndNLStr(&result, line)
continue
}

// Havent found a potential yaml block yet
if !inCode {
if match := commentMatcher.Find([]byte(line)); match != nil {
codeIndention = len(match)
inCode = true
}
}

// Try if this line is valid yaml
if inCode {
if commentMatcher.Match([]byte(line)) {
// Strip the commet away
strippedLine := line[codeIndention:]
// add it to the already parsed valid yaml
appendAndNLStr(&buff, strippedLine)
// check if the new block is still valid yaml
err := yaml.Unmarshal(buff, &unknownYaml)
if err != nil {
// Invalid yaml found,
// Remove the stripped line again
buff = buff[:len(buff)-len(strippedLine)-1]
// and add the commented line instead
appendAndNLStr(&buff, line)
}
// its still valid yaml
continue
}

// If the line is not a comment it must be yaml
appendAndNLStr(&buff, line)
continue
}
// line is valid yaml
appendAndNLStr(&result, line)
}

if len(buff) > 0 {
appendAndNL(&result, &buff)
}

return result, nil
}

0 comments on commit d6e8314

Please sign in to comment.