Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions internal/util/render/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ type Renderer struct {

// FileSystem is the input filesystem to operate on
FileSystem filesys.FileSystem

// DisplayName is an optional field to modify the package name displayed in logs
Comment thread
dgyorgy-nokia marked this conversation as resolved.
DisplayName string
}

// Execute runs a pipeline.
Expand All @@ -84,6 +87,7 @@ func (e *Renderer) Execute(ctx context.Context) (*fnresult.ResultList, error) {
// initialize hydration context
hctx := &hydrationContext{
root: root,
rootName: e.DisplayName,
pkgs: map[types.UniquePath]*pkgNode{},
fnResults: fnresult.NewResultList(),
runnerOptions: e.RunnerOptions,
Expand Down Expand Up @@ -349,6 +353,8 @@ type hydrationContext struct {

// function runtime
runtime fn.FunctionRuntime

rootName string
}

// pkgNode represents a package being hydrated. Think of it as a node in the hydration DAG.
Expand Down Expand Up @@ -709,7 +715,8 @@ func (pn *pkgNode) runPipeline(ctx context.Context, hctx *hydrationContext, inpu
// TODO: the DisplayPath is a relative file path. It cannot represent the
// package structure. We should have function to get the relative package
// path here.
pr.OptPrintf(printer.NewOpt().PkgDisplay(pn.pkg.DisplayPath), "\n")
prOpts := printer.NewOpt().PkgDisplay(pn.pkg.DisplayPath).PkgName(hctx.rootName)
Comment thread
dgyorgy-nokia marked this conversation as resolved.
pr.OptPrintf(prOpts, "\n")

pl, err := pn.pkg.Pipeline()
if err != nil {
Expand All @@ -730,11 +737,11 @@ func (pn *pkgNode) runPipeline(ctx context.Context, hctx *hydrationContext, inpu

mutatedResources, err := pn.runMutators(ctx, hctx, input)
if err != nil {
return mutatedResources, errors.E(op, pn.pkg.UniquePath, err)
return mutatedResources, errors.E(op, hctx.rootName, pn.pkg.UniquePath, err)
Comment thread
dgyorgy-nokia marked this conversation as resolved.
}

if err = pn.runValidators(ctx, hctx, mutatedResources); err != nil {
return mutatedResources, errors.E(op, pn.pkg.UniquePath, err)
return mutatedResources, errors.E(op, hctx.rootName, pn.pkg.UniquePath, err)
Comment thread
dgyorgy-nokia marked this conversation as resolved.
}
return mutatedResources, nil
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/fn/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import (
type RenderOptions struct {
PkgPath string
Runtime FunctionRuntime
// DisplayName is a human-readable name used for logs and diagnostics.
// It is not intended to be a unique or stable identifier; if empty, no
// explicit display name was provided.
DisplayName string
}
Comment thread
dgyorgy-nokia marked this conversation as resolved.

type Renderer interface {
Expand Down
12 changes: 8 additions & 4 deletions pkg/lib/kptops/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func (r *renderer) Render(ctx context.Context, pkg filesys.FileSystem, opts fn.R
rr := render.Renderer{
PkgPath: opts.PkgPath,
Runtime: opts.Runtime,
DisplayName: opts.DisplayName,
FileSystem: pkg,
RunnerOptions: r.runnerOptions,
}
Expand Down Expand Up @@ -77,10 +78,13 @@ func (p *packagePrinter) OptPrintf(opt *printer.Options, format string, args ...
return
}
var prefix string
if !opt.PkgDisplayPath.Empty() {
prefix = fmt.Sprintf(packagePrefixFormat, string(opt.PkgDisplayPath))
} else if !opt.PkgPath.Empty() {
prefix = fmt.Sprintf(packagePrefixFormat, string(opt.PkgPath))
switch {
case opt.PkgDisplayName != "":
prefix = fmt.Sprintf("Package %q: ", opt.PkgDisplayName)
case !opt.PkgDisplayPath.Empty():
prefix = fmt.Sprintf("Package %q: ", string(opt.PkgDisplayPath))
case !opt.PkgPath.Empty():
prefix = fmt.Sprintf("Package %q: ", string(opt.PkgPath))
Comment thread
dgyorgy-nokia marked this conversation as resolved.
}
Comment thread
dgyorgy-nokia marked this conversation as resolved.
p.printfDepth(logDepth, prefix+format, args...)
}
Expand Down
209 changes: 188 additions & 21 deletions pkg/lib/kptops/render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ package kptops

import (
"bytes"
"flag"
"io"
"os"
"path/filepath"
goruntime "runtime"
Expand All @@ -29,6 +29,8 @@ import (
"github.com/kptdev/kpt/pkg/lib/runneroptions"
"github.com/kptdev/kpt/pkg/printer"
"github.com/kptdev/kpt/pkg/printer/fake"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"k8s.io/klog/v2"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
Expand Down Expand Up @@ -89,36 +91,201 @@ func TestRender(t *testing.T) {
}

func TestPackagePrinter(t *testing.T) {
klog.InitFlags(nil)
_ = flag.Set("logtostderr", "false")
t.Run("PrintPackage without leading newline", func(t *testing.T) {
var errBuf bytes.Buffer
p := printer.New(io.Discard, &errBuf)

var buf bytes.Buffer
klog.SetOutput(&buf)
testPkg := &pkg.Pkg{
DisplayPath: "test/path",
}

p := &packagePrinter{}
p.PrintPackage(testPkg, false)

testPkg := &pkg.Pkg{DisplayPath: "test/path"}
p.PrintPackage(testPkg, false)
output := errBuf.String()
assert.Contains(t, output, "test/path")
assert.NotContains(t, output, "\n\nPackage")
})

opt := &printer.Options{
PkgDisplayPath: "display/path",
}
p.OptPrintf(opt, ": Hello %s", "World")
t.Run("PrintPackage with leading newline", func(t *testing.T) {
var errBuf bytes.Buffer
p := printer.New(io.Discard, &errBuf)

klog.Flush()
testPkg := &pkg.Pkg{
DisplayPath: "test/path",
}

got := buf.String()
p.PrintPackage(testPkg, true)

if !strings.Contains(got, `Package: "test/path"`) {
t.Errorf("PrintPackage output missing:\n%s", got)
}
if !strings.Contains(got, `Package: "display/path": Hello World`) {
t.Errorf("OptPrintf output missing:\n%s", got)
}
output := errBuf.String()
assert.Contains(t, output, "test/path")
assert.Contains(t, output, "\nPackage")
})

t.Run("Printf", func(t *testing.T) {
var errBuf bytes.Buffer
p := printer.New(io.Discard, &errBuf)

p.Printf("test message")
assert.Contains(t, errBuf.String(), "test message")

errBuf.Reset()
p.Printf("test message with args: %s %d", "hello", 42)
assert.Contains(t, errBuf.String(), "test message with args: hello 42")
})

t.Run("OptPrintf with nil options", func(t *testing.T) {
var errBuf bytes.Buffer
p := printer.New(io.Discard, &errBuf)

p.OptPrintf(nil, "test message")
assert.Contains(t, errBuf.String(), "test message")

errBuf.Reset()
p.OptPrintf(nil, "test with args: %s", "value")
assert.Contains(t, errBuf.String(), "test with args: value")
})

t.Run("OptPrintf with PkgDisplayName", func(t *testing.T) {
var errBuf bytes.Buffer
p := printer.New(io.Discard, &errBuf)

opt := printer.NewOpt().PkgName("my-package")

p.OptPrintf(opt, "test message")
output := errBuf.String()
assert.Contains(t, output, "my-package")
assert.Contains(t, output, "test message")
})

t.Run("OptPrintf with PkgDisplayPath", func(t *testing.T) {
var errBuf bytes.Buffer
p := printer.New(io.Discard, &errBuf)

opt := printer.NewOpt().PkgDisplay("display/path")

p.OptPrintf(opt, "test message")
output := errBuf.String()
assert.Contains(t, output, "display/path")
assert.Contains(t, output, "test message")
})

t.Run("OptPrintf with PkgPath", func(t *testing.T) {
var errBuf bytes.Buffer
p := printer.New(io.Discard, &errBuf)

opt := printer.NewOpt().Pkg("unique/path")

p.OptPrintf(opt, "test message")
output := errBuf.String()
assert.Contains(t, output, "unique/path")
assert.Contains(t, output, "test message")
})

t.Run("OptPrintf with multiple options set", func(t *testing.T) {
var errBuf bytes.Buffer
p := printer.New(io.Discard, &errBuf)

opt := printer.NewOpt().
PkgName("display-name").
PkgDisplay("display/path").
Pkg("unique/path")

p.OptPrintf(opt, "test message")
output := errBuf.String()
assert.Contains(t, output, "display-name")
assert.Contains(t, output, "test message")
})

t.Run("OutStream", func(t *testing.T) {
var outBuf bytes.Buffer
p := printer.New(&outBuf, io.Discard)

outStream := p.OutStream()
require.NotNil(t, outStream)

_, err := io.WriteString(outStream, "test output")
require.NoError(t, err)
assert.Equal(t, "test output", outBuf.String())
})

t.Run("ErrStream", func(t *testing.T) {
var errBuf bytes.Buffer
p := printer.New(io.Discard, &errBuf)

errStream := p.ErrStream()
require.NotNil(t, errStream)

_, err := io.WriteString(errStream, "test error")
require.NoError(t, err)
assert.Equal(t, "test error", errBuf.String())
})
}

func TestPackagePrinterStub(t *testing.T) {
t.Run("PrintPackage stub", func(t *testing.T) {
p := &packagePrinter{}
testPkg := &pkg.Pkg{
DisplayPath: "test/path",
}

assert.NotPanics(t, func() {
p.PrintPackage(testPkg, false)
})

assert.NotPanics(t, func() {
p.PrintPackage(testPkg, true)
})
})

t.Run("Printf stub", func(t *testing.T) {
p := &packagePrinter{}

assert.NotPanics(t, func() {
p.Printf("test message")
})

assert.NotPanics(t, func() {
p.Printf("test message with args: %s %d", "hello", 42)
})
})

t.Run("OptPrintf stub with nil options", func(t *testing.T) {
p := &packagePrinter{}

assert.NotPanics(t, func() {
p.OptPrintf(nil, "test message")
})
})

t.Run("OptPrintf stub with options", func(t *testing.T) {
p := &packagePrinter{}
opt := printer.NewOpt().PkgName("my-package")

assert.NotPanics(t, func() {
p.OptPrintf(opt, "test message")
})
})

t.Run("OutStream stub", func(t *testing.T) {
p := &packagePrinter{}

stream := p.OutStream()
assert.NotNil(t, stream)
assert.Equal(t, os.Stdout, stream)
})

t.Run("ErrStream stub", func(t *testing.T) {
p := &packagePrinter{}

stream := p.ErrStream()
assert.NotNil(t, stream)
assert.Equal(t, os.Stderr, stream)
})
}

func TestPrinterLoggingDepth(t *testing.T) {
_ = flag.Set("logtostderr", "false")
klog.LogToStderr(false)
defer klog.LogToStderr(true)

var buf bytes.Buffer
klog.SetOutput(&buf)
Expand Down
24 changes: 20 additions & 4 deletions pkg/printer/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ import (
// TruncateOutput defines should output be truncated
var TruncateOutput bool

const (
packagePrefixFormat = "Package: %q"
Comment thread
dgyorgy-nokia marked this conversation as resolved.
)

// Printer defines capabilities to display content in kpt CLI.
// The main intention, at the moment, is to abstract away printing
// output in the CLI so that we can evolve the kpt CLI UX.
Expand All @@ -45,6 +49,9 @@ type Options struct {
PkgPath types.UniquePath
// PkgDisplayPath is the display path for the package
PkgDisplayPath types.DisplayPath
// PkgDisplayName is the display name of the package.
// It takes precedence over PkgPath and PkgDisplayPath in most logging scenarios.
PkgDisplayName string
}

// NewOpt returns a pointer to new options
Expand All @@ -64,6 +71,12 @@ func (opt *Options) PkgDisplay(p types.DisplayPath) *Options {
return opt
}

// PkgName sets the package display name in options
func (opt *Options) PkgName(name string) *Options {
opt.PkgDisplayName = name
return opt
}
Comment thread
dgyorgy-nokia marked this conversation as resolved.

// New returns an instance of Printer.
func New(outStream, errStream io.Writer) Printer {
if outStream == nil {
Expand Down Expand Up @@ -128,15 +141,18 @@ func (pr *printer) OptPrintf(opt *Options, format string, args ...any) {
return
}
o := pr.errStream
if !opt.PkgDisplayPath.Empty() {
format = fmt.Sprintf("Package: %q", string(opt.PkgDisplayPath)) + format
} else if !opt.PkgPath.Empty() {
switch {
case opt.PkgDisplayName != "":
format = fmt.Sprintf(packagePrefixFormat, opt.PkgDisplayName) + format
case !opt.PkgDisplayPath.Empty():
format = fmt.Sprintf(packagePrefixFormat, string(opt.PkgDisplayPath)) + format
case !opt.PkgPath.Empty():
Comment thread
dgyorgy-nokia marked this conversation as resolved.
// try to print relative path of the pkg if we can else use abs path
relPath, err := opt.PkgPath.RelativePath()
if err != nil {
relPath = string(opt.PkgPath)
}
format = fmt.Sprintf("Package: %q", relPath) + format
format = fmt.Sprintf(packagePrefixFormat, relPath) + format
}
fmt.Fprintf(o, format, args...)
}
Expand Down
Loading