Repository: helm/helm
File: pkg/postrender/exec.go (Go)

Code before:
// Run the configured binary for the post render
func (p *execRender) Run(renderedManifests *bytes.Buffer) (*bytes.Buffer, error) {
	cmd := exec.Command(p.binaryPath, p.args...)
	stdin, err := cmd.StdinPipe()
	if err != nil {
		return nil, err
	}

	var postRendered = &bytes.Buffer{}
	var stderr = &bytes.Buffer{}
	cmd.Stdout = postRendered
	cmd.Stderr = stderr

	go func() {
		defer stdin.Close()
		io.Copy(stdin, renderedManifests)
	}()
	err = cmd.Run()
	if err != nil {
		return nil, errors.Wrapf(err, "error while running command %s. error output:\n%s", p.binaryPath, stderr.String())
	}

	// If the binary returned almost nothing, it's likely that it didn't
	// successfully render anything
	if len(bytes.TrimSpace(postRendered.Bytes())) == 0 {
		return nil, errors.Errorf("post render binary %s did not produce any output %s", p.binaryPath, postRendered.String())
	}

	return postRendered, nil
}

// getFullPath returns the full filepath to the binary to execute. If the path
// does not contain any separators, it will search in $PATH, otherwise it will
// resolve any relative paths to a fully qualified path
func getFullPath(binaryPath string) (string, error) {
	// NOTE(thomastaylor312): I am leaving this code commented out here. During
	// the implementation of post-render, it was brought up that if we are
	// relying on plugins, we should actually use the plugin system so it can
	// properly handle multiple OSs. This will be a feature add in the future,
	// so I left this code for reference. It can be deleted or reused once the
	// feature is implemented

	// Manually check the plugin dir first
	// if !strings.Contains(binaryPath, string(filepath.Separator)) {
	// 	// First check the plugin dir
	// 	pluginDir := helmpath.DataPath("plugins") // Default location
	// 	// If location for plugins is explicitly set, check there
	// 	if v, ok := os.LookupEnv("HELM_PLUGINS"); ok {
	// 		pluginDir = v
	// 	}
	// 	// The plugins variable can actually contain multiple paths, so loop through those

Review comment (suggestion):
nitpick on the error text:

```suggestion
		return nil, errors.Errorf("post-renderer %q produced empty output", p.binaryPath)
```

Code after:
// Run the configured binary for the post render
func (p *execRender) Run(renderedManifests *bytes.Buffer) (*bytes.Buffer, error) {
	cmd := exec.Command(p.binaryPath, p.args...)
	stdin, err := cmd.StdinPipe()
	if err != nil {
		return nil, err
	}

	var postRendered = &bytes.Buffer{}
	var stderr = &bytes.Buffer{}
	cmd.Stdout = postRendered
	cmd.Stderr = stderr

	go func() {
		defer stdin.Close()
		io.Copy(stdin, renderedManifests)
	}()
	err = cmd.Run()
	if err != nil {
		return nil, errors.Wrapf(err, "error while running command %s. error output:\n%s", p.binaryPath, stderr.String())
	}

	// If the binary returned almost nothing, it's likely that it didn't
	// successfully render anything
	if len(bytes.TrimSpace(postRendered.Bytes())) == 0 {
		return nil, errors.Errorf("post-renderer %q produced empty output", p.binaryPath)
	}

	return postRendered, nil
}

// getFullPath returns the full filepath to the binary to execute. If the path
// does not contain any separators, it will search in $PATH, otherwise it will
// resolve any relative paths to a fully qualified path
func getFullPath(binaryPath string) (string, error) {
	// NOTE(thomastaylor312): I am leaving this code commented out here. During
	// the implementation of post-render, it was brought up that if we are
	// relying on plugins, we should actually use the plugin system so it can
	// properly handle multiple OSs. This will be a feature add in the future,
	// so I left this code for reference. It can be deleted or reused once the
	// feature is implemented

	// Manually check the plugin dir first
	// if !strings.Contains(binaryPath, string(filepath.Separator)) {
	// 	// First check the plugin dir
	// 	pluginDir := helmpath.DataPath("plugins") // Default location
	// 	// If location for plugins is explicitly set, check there
	// 	if v, ok := os.LookupEnv("HELM_PLUGINS"); ok {
	// 		pluginDir = v
	// 	}
	// 	// The plugins variable can actually contain multiple paths, so loop through those