diff --git a/.helmdocsignore b/.helmdocsignore index 1871675..2dee046 100644 --- a/.helmdocsignore +++ b/.helmdocsignore @@ -1 +1,2 @@ -example-charts/ignored +example-charts/ignored-zero +example-charts/ignored-one/Chart.yaml diff --git a/Makefile b/Makefile index 6aec8b2..9ab90bb 100644 --- a/Makefile +++ b/Makefile @@ -12,4 +12,4 @@ test: .PHONY: clean clean: - rm helm-docs + rm -f helm-docs diff --git a/README.md b/README.md index bf806ef..b5501b4 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,8 @@ in the templates you supply. ## Ignoring Chart Directories helm-docs supports a `.helmdocsignore` file, exactly like a `.gitignore` file in which one can specify directories to ignore when searching for charts. Directories specified need not be charts themselves, so parent directories containing potentially -many charts can be ignored and none of the charts underneath them will be processed. +many charts can be ignored and none of the charts underneath them will be processed. You may also directly reference the +Chart.yaml file for a chart to skip processing for it. ## values.yaml metadata diff --git a/example-charts/ignored-one/Chart.yaml b/example-charts/ignored-one/Chart.yaml new file mode 100644 index 0000000..3d185a6 --- /dev/null +++ b/example-charts/ignored-one/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +name: ignored-one +description: A demonstration of the ability of a .helmdocsignore file to ignore files by Chart.yaml file +version: "0.2.0" +home: "https://github.com/norwoodj/helm-docs/tree/master/example-charts/ignored-one" +sources: ["https://github.com/norwoodj/helm-docs/tree/master/example-charts/ignored-one"] +engine: gotpl +maintainers: + - email: norwood.john.m@gmail.com + name: John Norwood diff --git a/example-charts/ignored/values.yaml b/example-charts/ignored-one/values.yaml similarity index 100% rename from example-charts/ignored/values.yaml rename to example-charts/ignored-one/values.yaml diff --git a/example-charts/ignored-zero/Chart.yaml b/example-charts/ignored-zero/Chart.yaml new file mode 100644 index 0000000..f48b57d --- /dev/null +++ b/example-charts/ignored-zero/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +name: ignored-zero +description: A demonstration of the ability of a .helmdocsignore file to ignore charts by directory name +version: "0.2.0" +home: "https://github.com/norwoodj/helm-docs/tree/master/example-charts/ignored-zero" +sources: ["https://github.com/norwoodj/helm-docs/tree/master/example-charts/ignored-zero"] +engine: gotpl +maintainers: + - email: norwood.john.m@gmail.com + name: John Norwood diff --git a/example-charts/ignored-zero/values.yaml b/example-charts/ignored-zero/values.yaml new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/example-charts/ignored-zero/values.yaml @@ -0,0 +1 @@ +{} diff --git a/example-charts/ignored/Chart.yaml b/example-charts/ignored/Chart.yaml deleted file mode 100644 index 7d28700..0000000 --- a/example-charts/ignored/Chart.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: v1 -name: ignored -description: ingored chart -version: "0.2.0" -home: "https://github.com/norwoodj/helm-docs/example-charts/ignored" -sources: ["https://github.com/norwoodj/helm-docs/example-charts/ignored"] -engine: gotpl -maintainers: - - email: norwood.john.m@gmail.com - name: John Norwood diff --git a/pkg/helm/chart_finder.go b/pkg/helm/chart_finder.go index 16d0b4c..65eca50 100644 --- a/pkg/helm/chart_finder.go +++ b/pkg/helm/chart_finder.go @@ -1,45 +1,37 @@ package helm import ( - "bufio" "os" "path/filepath" + "github.com/norwoodj/helm-docs/pkg/util" log "github.com/sirupsen/logrus" "github.com/spf13/viper" - "k8s.io/helm/pkg/ignore" ) -var defaultIgnore = map[string]bool{ - ".git": true, -} - func FindChartDirectories() ([]string, error) { - ignoreRules := ignore.Empty() ignoreFilename := viper.GetString("ignore-file") - ignoreFile, err := os.Open(ignoreFilename) - - if err == nil { - ignoreRules, err = ignore.Parse(bufio.NewReader(ignoreFile)) - - if err != nil { - log.Warnf("Failed to parse ignore rules from file %s", ignoreFilename) - ignoreRules = ignore.Empty() - } - } - + ignoreContext := util.NewIgnoreContext(ignoreFilename) chartDirs := make([]string, 0) - err = filepath.Walk(".", func(path string, info os.FileInfo, err error) error { + + err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error { if err != nil { return err } - if info.IsDir() && (ignoreRules.Ignore(path, info) || defaultIgnore[path]) { + absolutePath, _ := filepath.Abs(path) + + if info.IsDir() && ignoreContext.ShouldIgnore(absolutePath, info) { log.Debugf("Ignoring directory %s", path) return filepath.SkipDir } if filepath.Base(path) == "Chart.yaml" { + if ignoreContext.ShouldIgnore(absolutePath, info) { + log.Debugf("Ignoring chart file %s", path) + return nil + } + chartDirs = append(chartDirs, filepath.Dir(path)) } diff --git a/pkg/util/git.go b/pkg/util/git.go new file mode 100644 index 0000000..9d36efa --- /dev/null +++ b/pkg/util/git.go @@ -0,0 +1,16 @@ +package util + +import ( + "os/exec" + "strings" +) + +func FindGitRepositoryRoot() (string, error) { + path, err := exec.Command("git", "rev-parse", "--show-toplevel").Output() + + if err != nil { + return "", err + } + + return strings.TrimSpace(string(path)), nil +} diff --git a/pkg/util/ignore.go b/pkg/util/ignore.go new file mode 100644 index 0000000..dd38e74 --- /dev/null +++ b/pkg/util/ignore.go @@ -0,0 +1,78 @@ +package util + +import ( + "bufio" + "fmt" + "os" + "path/filepath" + + log "github.com/sirupsen/logrus" + "k8s.io/helm/pkg/ignore" +) + +var defaultIgnore = map[string]bool{ + ".git": true, +} + +type IgnoreContext struct { + rules *ignore.Rules + relativeDir string +} + +func parseIgnoreFilePathToRules(filename string) (*ignore.Rules, error) { + ignoreFile, err := os.Open(filename) + + if os.IsNotExist(err) { + log.Debugf("No ignore file found at %s, using empty ignore rules", filename) + return ignore.Empty(), nil + } + + if err != nil { + return nil, fmt.Errorf("failed to open ignore file at %s: %s", filename, err) + } + + ignoreRules, err := ignore.Parse(bufio.NewReader(ignoreFile)) + if err != nil { + return nil, fmt.Errorf("failed to parse ignore rules from file %s: %s", filename, err) + } + + return ignoreRules, nil +} + +func NewIgnoreContext(ignoreFilename string) IgnoreContext { + gitRepositoryRoot, err := FindGitRepositoryRoot() + + // If we got an error reading the repository root, then let's try for a ignore file in this directory + if err != nil { + ignoreRules, err := parseIgnoreFilePathToRules(ignoreFilename) + + if err != nil { + log.Warnf("Using empty ignore rules due to error: %s", err) + return IgnoreContext{rules: ignore.Empty()} + } + + absoluteWorkingDir, _ := filepath.Abs(".") + return IgnoreContext{rules: ignoreRules, relativeDir: absoluteWorkingDir} + } + + // Otherwise, let's look for a ignore file at the repository root and parse it, storing that files are ignored relative + // to that directory + ignoreRules, err := parseIgnoreFilePathToRules(filepath.Join(gitRepositoryRoot, ignoreFilename)) + + if err != nil { + log.Warnf("Using empty ignore rules due to error: %s", err) + return IgnoreContext{rules: ignoreRules} + } + + return IgnoreContext{rules: ignoreRules, relativeDir: gitRepositoryRoot} +} + +func (i IgnoreContext) ShouldIgnore(path string, fi os.FileInfo) bool { + pathRelativeToIgnoreFile, err := filepath.Rel(i.relativeDir, path) + + if err != nil { + return false + } + + return i.rules.Ignore(pathRelativeToIgnoreFile, fi) || defaultIgnore[pathRelativeToIgnoreFile] +}