func WrapWarnOutput(_ string, err error) {
	if err != nil {
		fmt.Fprintf(GinkgoWriter, "warning: %s", err)
	}
}
WrapWarnOutput is a one-liner to wrap an error from a command that returns (string, error) in a warning.
package testutils
import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strings"
	. "github.com/onsi/ginkgo"
	kbtestutils "sigs.k8s.io/kubebuilder/v3/test/e2e/utils"
)
type TestContext struct {
	*kbtestutils.TestContext
	BundleImageName string
	ProjectName string
	isPrometheusManagedBySuite bool
	isOLMManagedBySuite bool
}
func NewTestContext(binaryName string, env ...string) (tc TestContext, err error) {
	if tc.TestContext, err = kbtestutils.NewTestContext(binaryName, env...); err != nil {
		return tc, err
	}
	tc.ProjectName = strings.ToLower(filepath.Base(tc.Dir))
	tc.ImageName = makeImageName(tc.ProjectName)
	tc.BundleImageName = makeBundleImageName(tc.ProjectName)
	tc.isOLMManagedBySuite = true
	tc.isPrometheusManagedBySuite = true
	return tc, nil
}
func NewPartialTestContext(binaryName, dir string, env ...string) (tc TestContext, err error) {
	cc := &kbtestutils.CmdContext{
		Env: env,
	}
	if cc.Dir, err = filepath.Abs(dir); err != nil {
		return tc, err
	}
	projectName := strings.ToLower(filepath.Base(dir))
	return TestContext{
		TestContext: &kbtestutils.TestContext{
			CmdContext: cc,
			BinaryName: binaryName,
			ImageName:  makeImageName(projectName),
		},
		ProjectName:     projectName,
		BundleImageName: makeBundleImageName(projectName),
	}, nil
}
func makeImageName(projectName string) string {
	return fmt.Sprintf("quay.io/example/%s:v0.0.1", projectName)
}
func makeBundleImageName(projectName string) string {
	return fmt.Sprintf("quay.io/example/%s-bundle:v0.0.1", projectName)
}
func ReplaceInFile(path, old, new string) error {
	info, err := os.Stat(path)
	if err != nil {
		return err
	}
	b, err := ioutil.ReadFile(path)
	if err != nil {
		return err
	}
	if !strings.Contains(string(b), old) {
		return errors.New("unable to find the content to be replaced")
	}
	s := strings.Replace(string(b), old, new, -1)
	err = ioutil.WriteFile(path, []byte(s), info.Mode())
	if err != nil {
		return err
	}
	return nil
}
func ReplaceRegexInFile(path, match, replace string) error {
	matcher, err := regexp.Compile(match)
	if err != nil {
		return err
	}
	info, err := os.Stat(path)
	if err != nil {
		return err
	}
	b, err := ioutil.ReadFile(path)
	if err != nil {
		return err
	}
	s := matcher.ReplaceAllString(string(b), replace)
	if s == string(b) {
		return errors.New("unable to find the content to be replaced")
	}
	err = ioutil.WriteFile(path, []byte(s), info.Mode())
	if err != nil {
		return err
	}
	return nil
}
func UncommentCode(filename, target, prefix string) error {
	content, err := ioutil.ReadFile(filename)
	if err != nil {
		return err
	}
	strContent := string(content)
	idx := strings.Index(strContent, target)
	if idx < 0 {
		return fmt.Errorf("unable to find the code %s to be uncomment", target)
	}
	out := new(bytes.Buffer)
	_, err = out.Write(content[:idx])
	if err != nil {
		return err
	}
	scanner := bufio.NewScanner(bytes.NewBufferString(target))
	if !scanner.Scan() {
		return nil
	}
	for {
		_, err := out.WriteString(strings.TrimPrefix(scanner.Text(), prefix))
		if err != nil {
			return err
		}
		if !scanner.Scan() {
			break
		}
		if _, err := out.WriteString("\n"); err != nil {
			return err
		}
	}
	_, err = out.Write(content[idx+len(target):])
	if err != nil {
		return err
	}
	return ioutil.WriteFile(filename, out.Bytes(), 0644)
}