ronantakizawa/codereview-bench huggingface dataset:
Repository: helm/helm
File: pkg/repo/chartrepo_test.go (Go)

Code before:
)

const (
	testRepository = "testdata/repository"
	testURL        = "http://example-charts.com"
)

// loadFromDir a directory of charts archives (including sub-directories),
// appending to the repositores ChartPath
func loadFromDir(t *testing.T, r *ChartRepository, dir string) {
	dirInfo, err := os.Stat(dir)
	require.Nil(t, err)
	require.True(t, dirInfo.IsDir())

	globArchives := func(pattern string) []string {
		archives, err := filepath.Glob(filepath.Join(dir, pattern))
		require.Nil(t, err)

		return archives
	}

	r.ChartPaths = append(r.ChartPaths, globArchives("*.tgz")...)
	r.ChartPaths = append(r.ChartPaths, globArchives("**/*.tgz")...)
}

func TestIndex(t *testing.T) {
	r, err := NewChartRepository(&Entry{
		Name: testRepository,
		URL:  testURL,
	}, getter.All(&cli.EnvSettings{}))
	if err != nil {
		t.Errorf("Problem creating chart repository from %s: %v", testRepository, err)
	}

	loadFromDir(t, r, testRepository)

	err = r.Index()
	if err != nil {
		t.Errorf("Error performing index: %v\n", err)
	}

	tempIndexPath := filepath.Join(testRepository, indexPath)
	actual, err := LoadIndexFile(tempIndexPath)
	defer os.Remove(tempIndexPath) // clean up
	if err != nil {
		t.Errorf("Error loading index file %v", err)
	}
	verifyIndex(t, actual)

	// Re-index and test again.
	err = r.Index()

Review comment (refactor):
`TestIndex` which originally used the `Load(0` function I think needs to remain, as it is testing the `Index()` function (and no other test does)
So it now uses `loadFromDir()` as a test helper

Code after:
	repoUrls []string
}

func (g *CustomGetter) Get(href string, _ ...getter.Option) (*bytes.Buffer, error) {
	index := &IndexFile{
		APIVersion: "v1",
		Generated:  time.Now(),
	}
	indexBytes, err := yaml.Marshal(index)
	if err != nil {
		return nil, err
	}
	g.repoUrls = append(g.repoUrls, href)
	return bytes.NewBuffer(indexBytes), nil
}

func TestIndexCustomSchemeDownload(t *testing.T) {
	repoName := "gcs-repo"
	repoURL := "gs://some-gcs-bucket"
	myCustomGetter := &CustomGetter{}
	customGetterConstructor := func(_ ...getter.Option) (getter.Getter, error) {
		return myCustomGetter, nil
	}
	providers := getter.Providers{{
		Schemes: []string{"gs"},
		New:     customGetterConstructor,
	}}
	repo, err := NewChartRepository(&Entry{
		Name: repoName,
		URL:  repoURL,
	}, providers)
	if err != nil {
		t.Fatalf("Problem loading chart repository from %s: %v", repoURL, err)
	}
	repo.CachePath = t.TempDir()

	tempIndexFile, err := os.CreateTemp("", "test-repo")
	if err != nil {
		t.Fatalf("Failed to create temp index file: %v", err)
	}
	defer os.Remove(tempIndexFile.Name())

	idx, err := repo.DownloadIndexFile()
	if err != nil {
		t.Fatalf("Failed to download index file to %s: %v", idx, err)
	}

	if len(myCustomGetter.repoUrls) != 1 {
		t.Fatalf("Custom Getter.Get should be called once")
	}
Repository: helm/helm
File: pkg/repo/chartrepo_test.go (Go)

Code before:
	"bytes"
	"net/http"
	"net/http/httptest"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
	"sigs.k8s.io/yaml"

	"helm.sh/helm/v4/pkg/chart"
	"helm.sh/helm/v4/pkg/cli"
	"helm.sh/helm/v4/pkg/getter"
)

const (
	testRepository = "testdata/repository"
	testURL        = "http://example-charts.com"
)

// loadFromDir a directory of charts archives (including sub-directories),
// appending to the repositores ChartPath
func loadFromDir(t *testing.T, r *ChartRepository, dir string) {
	dirInfo, err := os.Stat(dir)
	require.Nil(t, err)
	require.True(t, dirInfo.IsDir())

	globArchives := func(pattern string) []string {
		archives, err := filepath.Glob(filepath.Join(dir, pattern))
		require.Nil(t, err)

		return archives
	}

	r.ChartPaths = append(r.ChartPaths, globArchives("*.tgz")...)
	r.ChartPaths = append(r.ChartPaths, globArchives("**/*.tgz")...)
}

func TestIndex(t *testing.T) {
	r, err := NewChartRepository(&Entry{
		Name: testRepository,
		URL:  testURL,
	}, getter.All(&cli.EnvSettings{}))
	if err != nil {
		t.Errorf("Problem creating chart repository from %s: %v", testRepository, err)
	}

	loadFromDir(t, r, testRepository)

Review comment (refactor):
I rewrote and simplified the original `Load()` function to this test helper, as it is still needed for `TestIndex`

Code after:
	"bytes"
	"net/http"
	"net/http/httptest"
	"os"
	"runtime"
	"strings"
	"testing"
	"time"

	"sigs.k8s.io/yaml"

	"helm.sh/helm/v4/pkg/cli"
	"helm.sh/helm/v4/pkg/getter"
)

type CustomGetter struct {
	repoUrls []string
}

func (g *CustomGetter) Get(href string, _ ...getter.Option) (*bytes.Buffer, error) {
	index := &IndexFile{
		APIVersion: "v1",
		Generated:  time.Now(),
	}
	indexBytes, err := yaml.Marshal(index)
	if err != nil {
		return nil, err
	}
	g.repoUrls = append(g.repoUrls, href)
	return bytes.NewBuffer(indexBytes), nil
}

func TestIndexCustomSchemeDownload(t *testing.T) {
	repoName := "gcs-repo"
	repoURL := "gs://some-gcs-bucket"
	myCustomGetter := &CustomGetter{}
	customGetterConstructor := func(_ ...getter.Option) (getter.Getter, error) {
		return myCustomGetter, nil
	}
	providers := getter.Providers{{
		Schemes: []string{"gs"},
		New:     customGetterConstructor,
	}}
	repo, err := NewChartRepository(&Entry{
		Name: repoName,
		URL:  repoURL,
	}, providers)
	if err != nil {
		t.Fatalf("Problem loading chart repository from %s: %v", repoURL, err)
	}
	repo.CachePath = t.TempDir()
Repository: helm/helm
File: pkg/engine/engine.go (Go)

Code before:
			traceable = TraceableError{
				location: templateName,
				message:  errMsg,
			}
		} else {
			return err
		}
		if len(fileLocations) > 0 {
			lastErr := fileLocations[len(fileLocations)-1]
			if lastErr.message == traceable.message &&
				lastErr.location == traceable.location &&
				lastErr.executedFunction == traceable.executedFunction {
				current = errors.Unwrap(current)
				continue
			}
		}
		fileLocations = append(fileLocations, traceable)
		current = errors.Unwrap(current)
	}

	finalErrorString := ""
	for _, fileLocation := range fileLocations {
		finalErrorString = finalErrorString + fileLocation.String()
	}

	if strings.TrimSpace(finalErrorString) == "" {
		// Fallback to original error message if nothing was extracted
		return err
	}

	return fmt.Errorf("%s", finalErrorString)
}

func sortTemplates(tpls map[string]renderable) []string {
	keys := make([]string, len(tpls))
	i := 0
	for key := range tpls {
		keys[i] = key
		i++
	}
	sort.Sort(sort.Reverse(byPathLen(keys)))
	return keys
}

type byPathLen []string

func (p byPathLen) Len() int      { return len(p) }
func (p byPathLen) Swap(i, j int) { p[j], p[i] = p[i], p[j] }
func (p byPathLen) Less(i, j int) bool {
	a, b := p[i], p[j]
	ca, cb := strings.Count(a, "/"), strings.Count(b, "/")

Review comment (bug):
Under what circumstance would `finalErrorString` actually be empty? This seems like an unusual way to catch/detect a failure?

Code after:
			traceable = TraceableError{
				location:         templateName,
				message:          errMsg,
				executedFunction: "executing " + functionName + " at " + locationName + ":",
			}
		} else if matches := execErrFmtWithoutTemplate.FindStringSubmatch(current.Error()); matches != nil {
			templateName := matches[execErrFmt.SubexpIndex("templateName")]
			errMsg := matches[execErrFmt.SubexpIndex("errMsg")]
			traceable = TraceableError{
				location: templateName,
				message:  errMsg,
			}
		} else if matches := execErrNoTemplateAssociated.FindStringSubmatch(current.Error()); matches != nil {
			traceable = TraceableError{
				message: current.Error(),
			}
		} else {
			return err
		}
		if len(fileLocations) == 0 || fileLocations[len(fileLocations)-1] != traceable {
			fileLocations = append(fileLocations, traceable)
		}
		current = errors.Unwrap(current)
	}

	var finalErrorString strings.Builder
	for _, fileLocation := range fileLocations {
		fmt.Fprintf(&finalErrorString, "%s", fileLocation.String())
	}

	return errors.New(strings.TrimSpace(finalErrorString.String()))
}

func sortTemplates(tpls map[string]renderable) []string {
	keys := make([]string, len(tpls))
	i := 0
	for key := range tpls {
		keys[i] = key
		i++
	}
	sort.Sort(sort.Reverse(byPathLen(keys)))
	return keys
}

type byPathLen []string

func (p byPathLen) Len() int      { return len(p) }
func (p byPathLen) Swap(i, j int) { p[j], p[i] = p[i], p[j] }
func (p byPathLen) Less(i, j int) bool {
	a, b := p[i], p[j]
	ca, cb := strings.Count(a, "/"), strings.Count(b, "/")
Repository: helm/helm
File: pkg/action/show.go (Go)

Code before:
	ShowValues ShowOutputFormat = "values"
	// ShowReadme is the format which only shows the chart's README
	ShowReadme ShowOutputFormat = "readme"
	// ShowCRDs is the format which only shows the chart's CRDs
	ShowCRDs ShowOutputFormat = "crds"
)

var readmeFileNames = []string{"readme.md", "readme.txt", "readme"}

func (o ShowOutputFormat) String() string {
	return string(o)
}

// Show is the action for checking a given release's information.
//
// It provides the implementation of 'helm show' and its respective subcommands.
type Show struct {
	ChartPathOptions
	Devel            bool
	OutputFormat     ShowOutputFormat
	JSONPathTemplate string
	chart            *chart.Chart // for testing
}

// NewShow creates a new Show object with the given configuration.
func NewShow2(output ShowOutputFormat, cfg *Configuration) *Show {
	sh := &Show{
		OutputFormat: output,
	}
	sh.ChartPathOptions.registryClient = cfg.RegistryClient

	return sh
}

// SetRegistryClient sets the registry client to use when pulling a chart from a registry.
func (s *Show) SetRegistryClient(client *registry.Client) {
	s.ChartPathOptions.registryClient = client
}

// Run executes 'helm show' against the given release.
func (s *Show) Run(chartpath string) (string, error) {
	if s.chart == nil {
		chrt, err := loader.Load(chartpath)
		if err != nil {
			return "", err
		}
		s.chart = chrt
	}
	cf, err := yaml.Marshal(s.chart.Metadata)
	if err != nil {
		return "", err

Review comment (suggestion):
```suggestion
func NewShow(output ShowOutputFormat, cfg *Configuration) *Show {
```

Code after:
	ShowValues ShowOutputFormat = "values"
	// ShowReadme is the format which only shows the chart's README
	ShowReadme ShowOutputFormat = "readme"
	// ShowCRDs is the format which only shows the chart's CRDs
	ShowCRDs ShowOutputFormat = "crds"
)

var readmeFileNames = []string{"readme.md", "readme.txt", "readme"}

func (o ShowOutputFormat) String() string {
	return string(o)
}

// Show is the action for checking a given release's information.
//
// It provides the implementation of 'helm show' and its respective subcommands.
type Show struct {
	ChartPathOptions
	Devel            bool
	OutputFormat     ShowOutputFormat
	JSONPathTemplate string
	chart            *chart.Chart // for testing
}

// NewShow creates a new Show object with the given configuration.
func NewShow(output ShowOutputFormat, cfg *Configuration) *Show {
	sh := &Show{
		OutputFormat: output,
	}
	sh.ChartPathOptions.registryClient = cfg.RegistryClient

	return sh
}

// SetRegistryClient sets the registry client to use when pulling a chart from a registry.
func (s *Show) SetRegistryClient(client *registry.Client) {
	s.ChartPathOptions.registryClient = client
}

// Run executes 'helm show' against the given release.
func (s *Show) Run(chartpath string) (string, error) {
	if s.chart == nil {
		chrt, err := loader.Load(chartpath)
		if err != nil {
			return "", err
		}
		s.chart = chrt
	}
	cf, err := yaml.Marshal(s.chart.Metadata)
	if err != nil {
		return "", err
Repository: helm/helm
File: pkg/chart/loader/load.go (Go)

Code before:
			sc, err = LoadArchive(bytes.NewBuffer(file.Data))
		default:
			// We have to trim the prefix off of every file, and ignore any file
			// that is in charts/, but isn't actually a chart.
			buff := make([]*BufferedFile, 0, len(files))
			for _, f := range files {
				parts := strings.SplitN(f.Name, "/", 2)
				if len(parts) < 2 {
					continue
				}
				f.Name = parts[1]
				buff = append(buff, f)
			}
			sc, err = LoadFiles(buff)
		}

		if err != nil {
			return c, errors.Wrapf(err, "error unpacking subchart %s in %s", n, c.Name())
		}
		c.AddDependency(sc)
	}

	return c, nil
}

func LoadValues(data []byte) (map[string]interface{}, error) {
	values := map[string]interface{}{}
	reader := utilyaml.NewYAMLReader(bufio.NewReader(bytes.NewReader(data)))
	for {
		currentMap := map[string]interface{}{}
		raw, err := reader.Read()
		if err != nil {
			if err == io.EOF {
				break
			}
			return nil, errors.Wrap(err, "error reading yaml document")
		}
		if err := yaml.Unmarshal(raw, &currentMap, func(d *json.Decoder) *json.Decoder {
			d.UseNumber()
			return d
		}); err != nil {
			return nil, errors.Wrap(err, "cannot unmarshal yaml document")
		}
		values = MergeMaps(values, currentMap)
	}
	return values, nil
}

func MergeMaps(a, b map[string]interface{}) map[string]interface{} {
	out := make(map[string]interface{}, len(a))
	for k, v := range a {

Review comment (suggestion):
```suggestion
func LoadValues(data io.Reader) (map[string]interface{}, error) {
```

It is preferred to take an interface that can support the necessary functionality, rather than a concrete type

Code after:
			sc, err = LoadArchive(bytes.NewBuffer(file.Data))
		default:
			// We have to trim the prefix off of every file, and ignore any file
			// that is in charts/, but isn't actually a chart.
			buff := make([]*BufferedFile, 0, len(files))
			for _, f := range files {
				parts := strings.SplitN(f.Name, "/", 2)
				if len(parts) < 2 {
					continue
				}
				f.Name = parts[1]
				buff = append(buff, f)
			}
			sc, err = LoadFiles(buff)
		}

		if err != nil {
			return c, errors.Wrapf(err, "error unpacking subchart %s in %s", n, c.Name())
		}
		c.AddDependency(sc)
	}

	return c, nil
}

// LoadValues loads values from a reader.
//
// The reader is expected to contain one or more YAML documents, the values of which are merged.
// And the values can be either a chart's default values or a user-supplied values.
func LoadValues(data io.Reader) (map[string]interface{}, error) {
	values := map[string]interface{}{}
	reader := utilyaml.NewYAMLReader(bufio.NewReader(data))
	for {
		currentMap := map[string]interface{}{}
		raw, err := reader.Read()
		if err != nil {
			if err == io.EOF {
				break
			}
			return nil, errors.Wrap(err, "error reading yaml document")
		}
		if err := yaml.Unmarshal(raw, &currentMap, func(d *json.Decoder) *json.Decoder {
			d.UseNumber()
			return d
		}); err != nil {
			return nil, errors.Wrap(err, "cannot unmarshal yaml document")
		}
		values = MergeMaps(values, currentMap)
	}
	return values, nil
}
Repository: helm/helm
File: pkg/chart/loader/load_test.go (Go)

Code before:
	illegalChart := filepath.Join(tmpdir, "abs-path.tgz")
	writeTar(illegalChart, "/Chart.yaml", []byte("hello: world"))
	_, err := Load(illegalChart)
	if err.Error() != "validation: chart.metadata.name is required" {
		t.Error(err)
	}

	// And just to validate that the above was not spurious
	illegalChart = filepath.Join(tmpdir, "abs-path2.tgz")
	writeTar(illegalChart, "files/whatever.yaml", []byte("hello: world"))
	_, err = Load(illegalChart)
	if err.Error() != "Chart.yaml file is missing" {
		t.Errorf("Unexpected error message: %s", err)
	}

	// Finally, test that drive letter gets stripped off on Windows
	illegalChart = filepath.Join(tmpdir, "abs-winpath.tgz")
	writeTar(illegalChart, "c:\\Chart.yaml", []byte("hello: world"))
	_, err = Load(illegalChart)
	if err.Error() != "validation: chart.metadata.name is required" {
		t.Error(err)
	}
}

func TestLoadValues(t *testing.T) {
	testDatas := []struct {
		name          string
		data          []byte
		expctedValues map[string]interface{}
	}{
		{
			name: "It should load values correctly",
			data: []byte(`
foo:
  image: foo:v1
bar:
  version: v2
`),
			expctedValues: map[string]interface{}{
				"foo": map[string]interface{}{
					"image": "foo:v1",
				},
				"bar": map[string]interface{}{
					"version": "v2",
				},
			},
		},
		{
			name: "It should load values correctly with multiple documents in one file",
			data: []byte(`
foo:

Review comment (suggestion):
nit: `testCases` might be better (and more consistent) naming/terminology here

```suggestion
	testCases := []struct {
```

Code after:
	illegalChart := filepath.Join(tmpdir, "abs-path.tgz")
	writeTar(illegalChart, "/Chart.yaml", []byte("hello: world"))
	_, err := Load(illegalChart)
	if err.Error() != "validation: chart.metadata.name is required" {
		t.Error(err)
	}

	// And just to validate that the above was not spurious
	illegalChart = filepath.Join(tmpdir, "abs-path2.tgz")
	writeTar(illegalChart, "files/whatever.yaml", []byte("hello: world"))
	_, err = Load(illegalChart)
	if err.Error() != "Chart.yaml file is missing" {
		t.Errorf("Unexpected error message: %s", err)
	}

	// Finally, test that drive letter gets stripped off on Windows
	illegalChart = filepath.Join(tmpdir, "abs-winpath.tgz")
	writeTar(illegalChart, "c:\\Chart.yaml", []byte("hello: world"))
	_, err = Load(illegalChart)
	if err.Error() != "validation: chart.metadata.name is required" {
		t.Error(err)
	}
}

func TestLoadValues(t *testing.T) {
	testCases := map[string]struct {
		data          []byte
		expctedValues map[string]interface{}
	}{
		"It should load values correctly": {
			data: []byte(`
foo:
  image: foo:v1
bar:
  version: v2
`),
			expctedValues: map[string]interface{}{
				"foo": map[string]interface{}{
					"image": "foo:v1",
				},
				"bar": map[string]interface{}{
					"version": "v2",
				},
			},
		},
		"It should load values correctly with multiple documents in one file": {
			data: []byte(`
foo:
  image: foo:v1
bar:
  version: v2
Repository: helm/helm
File: cmd/helm/flags.go (Go)

Code before:
	cmd.Flags().Var(&postRendererArgsSlice{p}, postRenderArgsFlag, "an argument to the post-renderer (can specify multiple)")
}

type postRendererOptions struct {
	renderer   *postrender.PostRenderer
	binaryPath string
	args       []string
}

type postRendererString struct {
	options *postRendererOptions
}

func (p *postRendererString) String() string {
	return p.options.binaryPath
}

func (p *postRendererString) Type() string {
	return "postRendererString"
}

func (p *postRendererString) Set(val string) error {
	if val == "" {
		return nil
	}
	if p.options.binaryPath != "" && p.options.binaryPath != val {
		return errors.Errorf("cannot set post-renderer more than once, given: %s, previous: %s", val, p.options.binaryPath)
	}
	p.options.binaryPath = val
	pr, err := postrender.NewExec(p.options.binaryPath, p.options.args...)
	if err != nil {
		return err
	}
	*p.options.renderer = pr
	return nil
}

type postRendererArgsSlice struct {
	options *postRendererOptions
}

func (p *postRendererArgsSlice) String() string {
	return "[" + strings.Join(p.options.args, ",") + "]"
}

func (p *postRendererArgsSlice) Type() string {
	return "postRendererArgsSlice"
}

func (p *postRendererArgsSlice) Set(val string) error {


Review comment (suggestion):
Is there a reason to support multiple usages with the same flag? Providing the flag mutliple times should be an error regardless IMHO

```suggestion
	if p.options.binaryPath != "" {
```



Code after:
}

type postRendererOptions struct {
	renderer   *postrender.PostRenderer
	binaryPath string
	args       []string
}

type postRendererString struct {
	options *postRendererOptions
}

func (p *postRendererString) String() string {
	return p.options.binaryPath
}

func (p *postRendererString) Type() string {
	return "postRendererString"
}

func (p *postRendererString) Set(val string) error {
	if val == "" {
		return nil
	}
	if p.options.binaryPath != "" {
		return fmt.Errorf("cannot specify --post-renderer flag more than once")
	}
	p.options.binaryPath = val
	pr, err := postrender.NewExec(p.options.binaryPath, p.options.args...)
	if err != nil {
		return err
	}
	*p.options.renderer = pr
	return nil
}

type postRendererArgsSlice struct {
	options *postRendererOptions
}

func (p *postRendererArgsSlice) String() string {
	return "[" + strings.Join(p.options.args, ",") + "]"
}

func (p *postRendererArgsSlice) Type() string {
	return "postRendererArgsSlice"
}

func (p *postRendererArgsSlice) Set(val string) error {

	// a post-renderer defined by a user may accept empty arguments
Repository: helm/helm
File: cmd/helm/flags.go (Go)

Code before:
}

type postRendererOptions struct {
	renderer   *postrender.PostRenderer
	binaryPath string
	args       []string
}

type postRendererString struct {
	options *postRendererOptions
}

func (p *postRendererString) String() string {
	return p.options.binaryPath
}

func (p *postRendererString) Type() string {
	return "postRendererString"
}

func (p *postRendererString) Set(val string) error {
	if val == "" {
		return nil
	}
	if p.options.binaryPath != "" && p.options.binaryPath != val {
		return errors.Errorf("cannot set post-renderer more than once, given: %s, previous: %s", val, p.options.binaryPath)
	}
	p.options.binaryPath = val
	pr, err := postrender.NewExec(p.options.binaryPath, p.options.args...)
	if err != nil {
		return err
	}
	*p.options.renderer = pr
	return nil
}

type postRendererArgsSlice struct {
	options *postRendererOptions
}

func (p *postRendererArgsSlice) String() string {
	return "[" + strings.Join(p.options.args, ",") + "]"
}

func (p *postRendererArgsSlice) Type() string {
	return "postRendererArgsSlice"
}

func (p *postRendererArgsSlice) Set(val string) error {

	// a post-renderer defined by a user may accept empty arguments

Review comment (suggestion):
I don't think we need to tell the user the values they supplied. Just stick to the pertinent message:

```suggestion
		return fmt.Errorf("cannot specify --post-renderer flag more than once")
```

Code after:

type postRendererOptions struct {
	renderer   *postrender.PostRenderer
	binaryPath string
	args       []string
}

type postRendererString struct {
	options *postRendererOptions
}

func (p *postRendererString) String() string {
	return p.options.binaryPath
}

func (p *postRendererString) Type() string {
	return "postRendererString"
}

func (p *postRendererString) Set(val string) error {
	if val == "" {
		return nil
	}
	if p.options.binaryPath != "" {
		return fmt.Errorf("cannot specify --post-renderer flag more than once")
	}
	p.options.binaryPath = val
	pr, err := postrender.NewExec(p.options.binaryPath, p.options.args...)
	if err != nil {
		return err
	}
	*p.options.renderer = pr
	return nil
}

type postRendererArgsSlice struct {
	options *postRendererOptions
}

func (p *postRendererArgsSlice) String() string {
	return "[" + strings.Join(p.options.args, ",") + "]"
}

func (p *postRendererArgsSlice) Type() string {
	return "postRendererArgsSlice"
}

func (p *postRendererArgsSlice) Set(val string) error {

	// a post-renderer defined by a user may accept empty arguments
	p.options.args = append(p.options.args, val)