Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
36 changes: 19 additions & 17 deletions cmd/pinning/pinning_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import (
"bytes"
"encoding/json"
"html/template"
"io/ioutil"
"os"
"path/filepath"

. "github.com/benjamintf1/unmarshalledmatchers"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/operator-framework/operator-manifest-tools/pkg/imageresolver"
"github.com/operator-framework/operator-manifest-tools/internal/utils"
"github.com/operator-framework/operator-manifest-tools/pkg/imageresolver"
"gopkg.in/yaml.v3"
)

Expand All @@ -35,13 +34,15 @@ var _ = Describe("pinning", func() {
// Delims("{", "}").Parse(CSV_TEMPLATE_WITH_RELATED_IMAGES))
resolved = template.Must(template.New("resolved").Parse(CSV_RESOLVED_TEMPLATE))

dir, _ = ioutil.TempDir("", "script")
manifestDir, _ = ioutil.TempDir("", "pinning_test_")
dir, err := os.MkdirTemp("", "script")
Expect(err).To(Succeed())
manifestDir, err = os.MkdirTemp("", "pinning_test_")
Expect(err).To(Succeed())
Comment thread
acornett21 marked this conversation as resolved.
csvFilePath = filepath.Join(manifestDir, "clusterserviceversion.yaml")

resolverScript := filepath.Join(dir, "resolver.sh")

ioutil.WriteFile(resolverScript, []byte(`#!/bin/bash
err = os.WriteFile(resolverScript, []byte(`#!/bin/bash
if [ "$1" == "registry.example.com/eggs:9.8" ]; then
echo -n "2"
exit 0
Expand All @@ -54,6 +55,7 @@ fi

exit 1
`), 0700)
Expect(err).To(Succeed())

resolver, _ = imageresolver.GetResolver(imageresolver.ResolverScript, map[string]string{
"path": resolverScript,
Expand Down Expand Up @@ -89,7 +91,7 @@ exit 1
extractData := bytes.Buffer{}
extract(manifestDir, &extractData)

extractJson := []interface{}{}
extractJson := []any{}

Expect(json.Unmarshal(extractData.Bytes(), &extractJson)).To(Succeed())
Expect(extractJson).To(HaveLen(2))
Expand Down Expand Up @@ -118,7 +120,7 @@ exit 1
},
})

extractData, _ = json.Marshal([]interface{}{
extractData, _ = json.Marshal([]any{
"registry.example.com/eggs:9.8",
"registry.example.com/maps/spam-operator:1.2",
})
Expand All @@ -129,11 +131,11 @@ exit 1
err := resolve(resolver, bytes.NewReader(extractData), &resolveData)
Expect(err).To(Succeed())

resolveJson := map[string]interface{}{}
resolveJson := map[string]any{}
Expect(json.Unmarshal(resolveData.Bytes(), &resolveJson)).To(Succeed())
Expect(resolveJson).To(HaveLen(2))
Expect(resolveJson).To(Equal(
map[string]interface{}{
map[string]any{
"registry.example.com/eggs:9.8": "registry.example.com/eggs@sha256:2",
"registry.example.com/maps/spam-operator:1.2": "registry.example.com/maps/spam-operator@sha256:1",
}))
Expand Down Expand Up @@ -177,7 +179,7 @@ exit 1

resolvedFile = resolvedFileBuffer.Bytes()

resolveData, _ = json.Marshal(map[string]interface{}{
resolveData, _ = json.Marshal(map[string]any{
"registry.example.com/eggs:9.8": "registry.example.com/eggs@sha256:2",
"registry.example.com/maps/spam-operator:1.2": "registry.example.com/maps/spam-operator@sha256:1",
})
Expand All @@ -187,7 +189,7 @@ exit 1
err := replace(manifestDir, bytes.NewReader(resolveData))
Expect(err).To(Succeed())

fileData, err := ioutil.ReadFile(csvFilePath)
fileData, err := os.ReadFile(csvFilePath)
Expect(err).To(Succeed())

Expect(fileData).To(MatchUnorderedYAML(resolvedFile))
Expand Down Expand Up @@ -220,12 +222,12 @@ exit 1
},
})

extractFile, err = ioutil.TempFile(dir, "extract")
extractFile, err = os.CreateTemp(dir, "extract")
Expect(err).To(Succeed())
outputExtract = utils.NewOutputParam()
outputExtract.Name = extractFile.Name()

replaceFile, err = ioutil.TempFile(dir, "replace")
replaceFile, err = os.CreateTemp(dir, "replace")
Expect(err).To(Succeed())
outputReplace = utils.NewOutputParam()
outputReplace.Name = replaceFile.Name()
Expand Down Expand Up @@ -261,7 +263,7 @@ exit 1
extractAnswer, err := os.ReadFile(outputExtract.Name)
Expect(err).To(Succeed())

extractJson := []interface{}{}
extractJson := []any{}

Expect(json.Unmarshal(extractAnswer, &extractJson)).To(Succeed())
Expect(extractJson).To(HaveLen(2))
Expand All @@ -271,11 +273,11 @@ exit 1
resolveAnswer, err := os.ReadFile(outputReplace.Name)
Expect(err).To(Succeed())

resolveJson := map[string]interface{}{}
resolveJson := map[string]any{}
Expect(json.Unmarshal(resolveAnswer, &resolveJson)).To(Succeed())
Expect(resolveJson).To(HaveLen(2))
Expect(resolveJson).To(Equal(
map[string]interface{}{
map[string]any{
"registry.example.com/eggs:9.8": "registry.example.com/eggs@sha256:2",
"registry.example.com/maps/spam-operator:1.2": "registry.example.com/maps/spam-operator@sha256:1",
}))
Expand All @@ -284,7 +286,7 @@ exit 1
Expect(err).To(Succeed())
Expect(replaceAnswer).To(MatchUnorderedYAML(resolvedFile))

validYaml := map[string]interface{}{}
validYaml := map[string]any{}
Expect(yaml.Unmarshal(replaceAnswer, &validYaml)).To(Succeed())
})
})
Expand Down
2 changes: 1 addition & 1 deletion internal/utils/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type errBase struct {
err error
}

func NewError(cause error, format string, args ...interface{}) error {
func NewError(cause error, format string, args ...any) error {
return errBase{
err: fmt.Errorf(format, args...),
cause: cause,
Expand Down
75 changes: 34 additions & 41 deletions internal/utils/lens.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,38 @@ import (

// lensBuilder is used to construct lens
type lensBuilder struct {
funcs []func(interface{}) (interface{}, error)
funcs []func(any) (any, error)
path []string
}

// lens holds a series of functions that helps navigate a map[string]interface{} data structure
// lens holds a series of functions that helps navigate a map[string]any data structure
type lens struct {
funcs []func(interface{}) (interface{}, error)
funcs []func(any) (any, error)
}

// newLens creates a new lens builder
func Lens() *lensBuilder {
return &lensBuilder{
funcs: []func(interface{}) (interface{}, error){},
funcs: []func(any) (any, error){},
path: []string{},
}
}

// L will create a step on a lens to navigate a slice by integer
func (d *lensBuilder) L(i int) *lensBuilder {
d.path = append(d.path, strconv.Itoa(i))
d.funcs = append(d.funcs, func(data interface{}) (interface{}, error) {
localI := i
slice, ok := data.([]interface{})
d.funcs = append(d.funcs, func(data any) (any, error) {
slice, ok := data.([]any)

if !ok {
return nil, NewError(ErrNotFound, "expected a []interface{} type on step %s path %s", strconv.Itoa(localI), strings.Join(d.path, ","))
return nil, NewError(ErrNotFound, "expected a []any type on step %s path %s", strconv.Itoa(i), strings.Join(d.path, ","))
}

if i < 0 || i >= len(slice) {
return nil, NewError(ErrNotFound, "not found on step %s path %s", strconv.Itoa(localI), strings.Join(d.path, ","))
return nil, NewError(ErrNotFound, "not found on step %s path %s", strconv.Itoa(i), strings.Join(d.path, ","))
}

return slice[localI], nil
return slice[i], nil
})

return d
Expand All @@ -48,17 +47,16 @@ func (d *lensBuilder) L(i int) *lensBuilder {
// M will create a step on a lens to navigate a map by a key
func (d *lensBuilder) M(key string) *lensBuilder {
d.path = append(d.path, key)
d.funcs = append(d.funcs, func(data interface{}) (interface{}, error) {
localKey := key
mmap, ok := data.(map[string]interface{})
d.funcs = append(d.funcs, func(data any) (any, error) {
mmap, ok := data.(map[string]any)

if !ok {
return nil, NewError(ErrNotFound, "expected a map[string]interface{} type on step %s path %s", localKey, strings.Join(d.path, ","))
return nil, NewError(ErrNotFound, "expected a map[string]any type on step %s path %s", key, strings.Join(d.path, ","))
}

v, ok := mmap[key]
if !ok {
return nil, NewError(ErrNotFound, "not found on step %s path %s", localKey, strings.Join(d.path, ","))
return nil, NewError(ErrNotFound, "not found on step %s path %s", key, strings.Join(d.path, ","))
}

return v, nil
Expand All @@ -70,20 +68,19 @@ func (d *lensBuilder) M(key string) *lensBuilder {
// lens to each element.
func (d *lensBuilder) Apply(l lens) *lensBuilder {
d.path = append(d.path, "*")
d.funcs = append(d.funcs, func(data interface{}) (interface{}, error) {
localLens := l
slice, ok := data.([]interface{})
d.funcs = append(d.funcs, func(data any) (any, error) {
slice, ok := data.([]any)

if !ok {
return nil, NewError(ErrNotFound, "expected a []interface{} type on step * path %s", strings.Join(d.path, ","))
return nil, NewError(ErrNotFound, "expected a []any type on step * path %s", strings.Join(d.path, ","))
}

results := make([]interface{}, 0, len(slice))
results := make([]any, 0, len(slice))

for i := range slice {
data := slice[i]

result, err := localLens.Lookup(data)
result, err := l.Lookup(data)

if err != nil {
continue
Expand All @@ -101,20 +98,16 @@ func (d *lensBuilder) Apply(l lens) *lensBuilder {

// Build finalizes the lens steps and makes it able to return results.
func (d *lensBuilder) Build() lens {
funcs := make([]func(interface{}) (interface{}, error), 0, len(d.funcs))

for i := range d.funcs {
localFunc := d.funcs[i]
funcs = append(funcs, localFunc)
}
funcs := make([]func(any) (any, error), 0, len(d.funcs))
funcs = append(funcs, d.funcs...)

return lens{
funcs: funcs,
}
}

// Lookup will run the lens against data, returning a result or error.
func (l lens) Lookup(data interface{}) (result interface{}, err error) {
func (l lens) Lookup(data any) (result any, err error) {
result = data
for _, fun := range l.funcs {
result, err = fun(result)
Expand All @@ -128,51 +121,51 @@ func (l lens) Lookup(data interface{}) (result interface{}, err error) {
}

// L is an alias for Lookup that will attempt to map the result of the lookup to a slice.
func (l lens) L(data interface{}) ([]interface{}, error) {
func (l lens) L(data any) ([]any, error) {
answer, err := l.Lookup(data)

if err != nil {
return nil, err
}

listAnswer, ok := answer.([]interface{})
listAnswer, ok := answer.([]any)

if !ok {
return nil, NewError(nil, "expected a []interface{} type")
return nil, NewError(nil, "expected a []any type")
}

return listAnswer, nil
}

// LFunc is an alias for Lookup that will attempt to map the result of the lookup to a slice and wrap
// the results in a callback.
func (l lens) LFunc(data interface{}) func() ([]interface{}, error) {
return func() ([]interface{}, error) {
func (l lens) LFunc(data any) func() ([]any, error) {
return func() ([]any, error) {
return l.L(data)
}
}

// M is an alias for Lookup that will attempt to map the result of the lookup to a map[string]interface{}.
func (l lens) M(data interface{}) (map[string]interface{}, error) {
// M is an alias for Lookup that will attempt to map the result of the lookup to a map[string]any.
func (l lens) M(data any) (map[string]any, error) {
answer, err := l.Lookup(data)

if err != nil {
return nil, err
}

mapAnswer, ok := answer.(map[string]interface{})
mapAnswer, ok := answer.(map[string]any)

if !ok {
return nil, NewError(nil, "expected a []interface{} type")
return nil, NewError(nil, "expected a map[string]any type but got a %T instead", answer)
}
Comment thread
caxu-rh marked this conversation as resolved.

return mapAnswer, nil
}

// M is an alias for Lookup that will attempt to map the result of the lookup to a map[string]interface{} and wrap
// the resutls in a callback.
func (l lens) MFunc(data interface{}) func() (map[string]interface{}, error) {
return func() (map[string]interface{}, error) {
// M is an alias for Lookup that will attempt to map the result of the lookup to a map[string]any and wrap
// the results in a callback.
func (l lens) MFunc(data any) func() (map[string]any, error) {
return func() (map[string]any, error) {
return l.M(data)
}
}
12 changes: 6 additions & 6 deletions internal/utils/lens_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import (
)

var _ = Describe("lens", func() {
var data map[string]interface{}
var data map[string]any
BeforeEach(func() {
data = map[string]interface{}{
data = map[string]any{
"a": "b",
"c": []interface{}{
map[string]interface{}{
"c": []any{
map[string]any{
"d": 1,
},
map[string]interface{}{
map[string]any{
"d": 2,
},
},
Expand Down Expand Up @@ -63,7 +63,7 @@ var _ = Describe("lens", func() {
myLens := Lens().M("c").Apply(Lens().M("d").Build()).Build()
answer, err := myLens.L(data)
Expect(err).To(Succeed())
Expect(answer).To(Equal([]interface{}{1, 2}))
Expect(answer).To(Equal([]any{1, 2}))

myLens = Lens().M("c").Apply(Lens().M("nothere").Build()).Build()
answer, err = myLens.L(data)
Expand Down
7 changes: 4 additions & 3 deletions internal/utils/vars_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package utils
import (
"bytes"
"io"
"io/ioutil"
"os"
"path/filepath"

Expand Down Expand Up @@ -31,11 +30,13 @@ var _ = Describe("Vars", func() {
})

It("should and open a file if a valid filepath", func() {
f, err := ioutil.TempFile(os.TempDir(), "file-*.txt")
f, err := os.CreateTemp(os.TempDir(), "file-*.txt")
Expect(err).To(Succeed())
defer os.Remove(f.Name())
Comment thread
caxu-rh marked this conversation as resolved.
defer f.Close()

ioutil.WriteFile(f.Name(), []byte("foo"), 0666)
err = os.WriteFile(f.Name(), []byte("foo"), 0666)
Expect(err).To(Succeed())

sut.Name = f.Name()

Expand Down
Loading
Loading