Skip to content

Commit 45ed61d

Browse files
authored
Merge pull request #32 from ecordell/nohasherror
hash: remove errors from api (breaking api change)
2 parents 3b0fa4d + 8d358d6 commit 45ed61d

File tree

7 files changed

+546
-31
lines changed

7 files changed

+546
-31
lines changed

.golangci.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ linters:
77
enable:
88
- "bidichk"
99
- "bodyclose"
10-
- "deadcode"
1110
- "errcheck"
1211
- "errname"
1312
- "errorlint"
@@ -17,7 +16,6 @@ linters:
1716
- "gosec"
1817
- "gosimple"
1918
- "govet"
20-
- "ifshort"
2119
- "importas"
2220
- "ineffassign"
2321
- "makezero"
@@ -27,12 +25,10 @@ linters:
2725
- "revive"
2826
- "rowserrcheck"
2927
- "staticcheck"
30-
- "structcheck"
3128
- "stylecheck"
3229
- "tenv"
3330
- "typecheck"
3431
- "unconvert"
3532
- "unused"
36-
- "varcheck"
3733
- "wastedassign"
3834
- "whitespace"

component/ensure_component.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,7 @@ func (e *EnsureComponentByHash[K, A]) Handle(ctx context.Context) {
5555
ownedObjs := e.List(ctx, e.nn.MustValue(ctx))
5656

5757
newObj := e.newObj(ctx)
58-
hash, err := e.Hash(newObj)
59-
if err != nil {
60-
e.ctrls.RequeueErr(ctx, err)
61-
return
62-
}
58+
hash := e.Hash(newObj)
6359
newObj = newObj.WithAnnotations(map[string]string{e.HashAnnotationKey: hash})
6460

6561
matchingObjs := make([]K, 0)
@@ -78,7 +74,7 @@ func (e *EnsureComponentByHash[K, A]) Handle(ctx context.Context) {
7874

7975
if len(matchingObjs) == 0 {
8076
// apply if no matching KubeObject in cluster
81-
_, err = e.applyObject(ctx, newObj)
77+
_, err := e.applyObject(ctx, newObj)
8278
if err != nil {
8379
e.ctrls.RequeueErr(ctx, err)
8480
return

hash/hash.go

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ import (
1313
)
1414

1515
type (
16-
ObjectHashFunc func(obj any) (string, error)
16+
ObjectHashFunc func(obj any) string
1717
EqualFunc func(a, b string) bool
1818
)
1919

2020
// ObjectHasher hashes and object and can compare hashes for equality
2121
type ObjectHasher interface {
22-
Hash(obj any) (string, error)
22+
Hash(obj any) string
2323
Equal(a, b string) bool
2424
}
2525

@@ -28,7 +28,7 @@ type hasher struct {
2828
EqualFunc
2929
}
3030

31-
func (h *hasher) Hash(obj interface{}) (string, error) {
31+
func (h *hasher) Hash(obj interface{}) string {
3232
return h.ObjectHashFunc(obj)
3333
}
3434

@@ -54,25 +54,24 @@ func NewObjectHash() ObjectHasher {
5454

5555
// SecureObject canonicalizes the object before hashing with sha512 and then
5656
// with xxhash
57-
func SecureObject(obj interface{}) (string, error) {
57+
func SecureObject(obj interface{}) string {
5858
hasher := sha512.New512_256()
5959
printer := spew.ConfigState{
6060
Indent: " ",
6161
SortKeys: true,
6262
DisableMethods: true,
6363
SpewKeys: true,
6464
}
65-
_, err := printer.Fprintf(hasher, "%#v", obj)
66-
if err != nil {
67-
return "", err
68-
}
65+
// sha512's hasher.Write never returns an error, and Fprintf just passes up
66+
// the underlying Write call's error, so we can safely ignore the error here
67+
_, _ = printer.Fprintf(hasher, "%#v", obj)
6968
// xxhash the sha512 hash to get a shorter value
7069
xxhasher := xxhash.New()
71-
_, err = xxhasher.Write(hasher.Sum(nil))
72-
if err != nil {
73-
return "", err
74-
}
75-
return rand.SafeEncodeString(fmt.Sprint(xxhasher.Sum(nil))), nil
70+
71+
// xxhash's hasher.Write never returns an error, so we can safely ignore
72+
// the error here tpp
73+
_, _ = xxhasher.Write(hasher.Sum(nil))
74+
return rand.SafeEncodeString(fmt.Sprint(xxhasher.Sum(nil)))
7675
}
7776

7877
// SecureEqual compares hashes safely
@@ -81,19 +80,19 @@ func SecureEqual(a, b string) bool {
8180
}
8281

8382
// Object canonicalizes the object before hashing with xxhash
84-
func Object(obj interface{}) (string, error) {
83+
func Object(obj interface{}) string {
8584
hasher := xxhash.New()
8685
printer := spew.ConfigState{
8786
Indent: " ",
8887
SortKeys: true,
8988
DisableMethods: true,
9089
SpewKeys: true,
9190
}
92-
_, err := printer.Fprintf(hasher, "%#v", obj)
93-
if err != nil {
94-
return "", err
95-
}
96-
return rand.SafeEncodeString(fmt.Sprint(hasher.Sum(nil))), nil
91+
92+
// xxhash's hasher.Write never returns an error, and Fprintf just passes up
93+
// the underlying Write call's error, so we can safely ignore the error here
94+
_, _ = printer.Fprintf(hasher, "%#v", obj)
95+
return rand.SafeEncodeString(fmt.Sprint(hasher.Sum(nil)))
9796
}
9897

9998
// Equal compares hashes safely

hash/hash_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ func ExampleObject() {
1212
"some": "data",
1313
},
1414
}
15-
hash, _ := Object(configmap)
15+
hash := Object(configmap)
1616
fmt.Println(Equal(hash, "n688h54h56ch64bh677h55fh648hddq"))
1717
// Output: true
1818
}
@@ -23,7 +23,7 @@ func ExampleSecureObject() {
2323
"some": "data",
2424
},
2525
}
26-
hash, _ := SecureObject(secret)
26+
hash := SecureObject(secret)
2727
fmt.Println(SecureEqual(hash, "n665hb8h667h68hfbhffh669h54dq"))
2828
// Output: true
2929
}

hash/set.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package hash
2+
3+
// Set is a set that stores objects based on their Object hash
4+
type Set[T any] map[string]T
5+
6+
// NewSet creates a set from a list of objects
7+
func NewSet[T any](objects ...T) Set[T] {
8+
set := make(map[string]T, len(objects))
9+
for _, o := range objects {
10+
set[Object(o)] = o
11+
}
12+
return set
13+
}
14+
15+
// Has returns true if all objects are already in the set
16+
func (s Set[T]) Has(objects ...T) bool {
17+
for _, o := range objects {
18+
_, ok := s[Object(o)]
19+
if !ok {
20+
return false
21+
}
22+
}
23+
return true
24+
}
25+
26+
// Insert adds all objects to the set
27+
func (s Set[T]) Insert(objects ...T) Set[T] {
28+
for _, o := range objects {
29+
s[Object(o)] = o
30+
}
31+
return s
32+
}
33+
34+
// Delete removes all objects from the set
35+
func (s Set[T]) Delete(objects ...T) Set[T] {
36+
for _, o := range objects {
37+
delete(s, Object(o))
38+
}
39+
return s
40+
}
41+
42+
// Len returns the number of objects in the set
43+
func (s Set[T]) Len() int {
44+
return len(s)
45+
}
46+
47+
// Intersect returns a new set containing all the elements common to both.
48+
// The new set will contain the object values from the receiver, not from the
49+
// argument.
50+
func (s Set[T]) Intersect(other Set[T]) Set[T] {
51+
out := NewSet[T]()
52+
for h, o := range s {
53+
if _, ok := other[h]; ok {
54+
out[h] = o
55+
}
56+
}
57+
return out
58+
}
59+
60+
// SetDifference returns the set of objects in s that are not in other.
61+
func (s Set[T]) SetDifference(other Set[T]) Set[T] {
62+
result := NewSet[T]()
63+
for h, o := range s {
64+
if _, ok := other[h]; !ok {
65+
result[h] = o
66+
}
67+
}
68+
return result
69+
}
70+
71+
// Union returns the set of objects common to both sets.
72+
func (s Set[T]) Union(other Set[T]) Set[T] {
73+
result := NewSet[T]()
74+
for h, o := range other {
75+
result[h] = o
76+
}
77+
for h, o := range s {
78+
result[h] = o
79+
}
80+
return result
81+
}
82+
83+
// Contains returns true if all elements of other can be found in s.
84+
func (s Set[T]) Contains(other Set[T]) bool {
85+
for h := range other {
86+
if _, ok := s[h]; !ok {
87+
return false
88+
}
89+
}
90+
return true
91+
}
92+
93+
// EqualElements returns true if both sets have equal elements.
94+
func (s Set[T]) EqualElements(other Set[T]) bool {
95+
return s.Len() == other.Len() && s.Contains(other)
96+
}
97+
98+
// Pop removes and returns a single element from the set, and a bool indicating
99+
// whether an element was found to pop.
100+
func (s Set[T]) Pop() (T, bool) {
101+
for h, o := range s {
102+
delete(s, h)
103+
return o, true
104+
}
105+
var zero T
106+
return zero, false
107+
}

0 commit comments

Comments
 (0)