mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
helpers: provide a few generic helper functions
This PR deprecates some functions in favor of generic alternatives. The new functions are compatible only with Nomad v1.4+. The old functions (nor their use) should not be removed until Nomad v1.6+.
This commit is contained in:
4
go.mod
4
go.mod
@@ -109,7 +109,7 @@ require (
|
||||
github.com/ryanuber/go-glob v1.0.0
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529
|
||||
github.com/shirou/gopsutil/v3 v3.21.12
|
||||
github.com/shoenig/test v0.2.5
|
||||
github.com/shoenig/test v0.2.6
|
||||
github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c
|
||||
github.com/stretchr/testify v1.7.1
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
|
||||
@@ -118,6 +118,7 @@ require (
|
||||
go.etcd.io/bbolt v1.3.5
|
||||
go.uber.org/goleak v1.1.12
|
||||
golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167
|
||||
golang.org/x/exp v0.0.0-20220609121020-a51bd0440498
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e
|
||||
@@ -264,7 +265,6 @@ require (
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/tools v0.1.10 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
google.golang.org/api v0.60.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
|
||||
7
go.sum
7
go.sum
@@ -1166,8 +1166,8 @@ github.com/shirou/gopsutil v0.0.0-20181107111621-48177ef5f880/go.mod h1:5b4v6he4
|
||||
github.com/shirou/gopsutil/v3 v3.21.12 h1:VoGxEW2hpmz0Vt3wUvHIl9fquzYLNpVpgNNB7pGJimA=
|
||||
github.com/shirou/gopsutil/v3 v3.21.12/go.mod h1:BToYZVTlSVlfazpDDYFnsVZLaoRG+g8ufT6fPQLdJzA=
|
||||
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
|
||||
github.com/shoenig/test v0.2.5 h1:CfxxPAhW9sJt9nVI39cOHrb4krmHd28SmU66oCXi6sY=
|
||||
github.com/shoenig/test v0.2.5/go.mod h1:xYtyGBC5Q3kzCNyJg/SjgNpfAa2kvmgA0i5+lQso8x0=
|
||||
github.com/shoenig/test v0.2.6 h1:G7QP1jygTmhhNc0TKZ5O87CvB919YjL8EXnsD1aiaHo=
|
||||
github.com/shoenig/test v0.2.6/go.mod h1:xYtyGBC5Q3kzCNyJg/SjgNpfAa2kvmgA0i5+lQso8x0=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
@@ -1341,6 +1341,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20220609121020-a51bd0440498 h1:TF0FvLUGEq/8wOt/9AV1nj6D4ViZGUIGCMQfCv7VRXY=
|
||||
golang.org/x/exp v0.0.0-20220609121020-a51bd0440498/go.mod h1:yh0Ynu2b5ZUe3MQfp2nM0ecK7wsgouWTDN0FNeJuIys=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -1660,7 +1662,6 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
|
||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
multierror "github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/hcl/hcl/ast"
|
||||
"golang.org/x/exp/constraints"
|
||||
)
|
||||
|
||||
// validUUID is used to check if a given string looks like a UUID
|
||||
@@ -69,41 +70,57 @@ func HashUUID(input string) (output string, hashed bool) {
|
||||
}
|
||||
|
||||
// BoolToPtr returns the pointer to a boolean.
|
||||
//
|
||||
// Deprecated; use pointer.Of instead.
|
||||
func BoolToPtr(b bool) *bool {
|
||||
return &b
|
||||
}
|
||||
|
||||
// IntToPtr returns the pointer to an int
|
||||
// IntToPtr returns the pointer to an int.
|
||||
//
|
||||
// Deprecated; use pointer.Of instead.
|
||||
func IntToPtr(i int) *int {
|
||||
return &i
|
||||
}
|
||||
|
||||
// Int8ToPtr returns the pointer to an int8
|
||||
// Int8ToPtr returns the pointer to an int8.
|
||||
//
|
||||
// Deprecated; use pointer.Of instead.
|
||||
func Int8ToPtr(i int8) *int8 {
|
||||
return &i
|
||||
}
|
||||
|
||||
// Int32ToPtr returns the pointer to an int32
|
||||
// Int32ToPtr returns the pointer to an int32.
|
||||
//
|
||||
// Deprecated; use pointer.Of instead.
|
||||
func Int32ToPtr(i int32) *int32 {
|
||||
return &i
|
||||
}
|
||||
|
||||
// Int64ToPtr returns the pointer to an int64
|
||||
// Int64ToPtr returns the pointer to an int64.
|
||||
//
|
||||
// Deprecated; use pointer.Of instead.
|
||||
func Int64ToPtr(i int64) *int64 {
|
||||
return &i
|
||||
}
|
||||
|
||||
// Uint64ToPtr returns the pointer to an uint64
|
||||
// Uint64ToPtr returns the pointer to an uint64.
|
||||
//
|
||||
// Deprecated; use pointer.Of instead.
|
||||
func Uint64ToPtr(u uint64) *uint64 {
|
||||
return &u
|
||||
}
|
||||
|
||||
// UintToPtr returns the pointer to an uint
|
||||
// UintToPtr returns the pointer to an uint.
|
||||
//
|
||||
// Deprecated; use pointer.Of instead.
|
||||
func UintToPtr(u uint) *uint {
|
||||
return &u
|
||||
}
|
||||
|
||||
// StringToPtr returns the pointer to a string
|
||||
// StringToPtr returns the pointer to a string.
|
||||
//
|
||||
// Deprecated; use pointer.Of instead.
|
||||
func StringToPtr(str string) *string {
|
||||
return &str
|
||||
}
|
||||
@@ -121,11 +138,32 @@ func CompareTimePtrs(a, b *time.Duration) bool {
|
||||
return *a == *b
|
||||
}
|
||||
|
||||
// Float64ToPtr returns the pointer to an float64
|
||||
// Float64ToPtr returns the pointer to an float64.
|
||||
//
|
||||
// Deprecated; use pointer.Of instead.
|
||||
func Float64ToPtr(f float64) *float64 {
|
||||
return &f
|
||||
}
|
||||
|
||||
// Min returns the minimum of a and b.
|
||||
func Min[T constraints.Ordered](a, b T) T {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// Max returns the maximum of a and b.
|
||||
func Max[T constraints.Ordered](a, b T) T {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// IntMin returns the minimum of a and b.
|
||||
//
|
||||
// Deprecated; use Min instead.
|
||||
func IntMin(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
@@ -133,6 +171,9 @@ func IntMin(a, b int) int {
|
||||
return b
|
||||
}
|
||||
|
||||
// IntMax returns the maximum of a and b.
|
||||
//
|
||||
// Deprecated; use Max instead.
|
||||
func IntMax(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
@@ -140,6 +181,9 @@ func IntMax(a, b int) int {
|
||||
return b
|
||||
}
|
||||
|
||||
// Uint64Max returns the maximum of a and b.
|
||||
//
|
||||
// Deprecated; use Max instead.
|
||||
func Uint64Max(a, b uint64) uint64 {
|
||||
if a > b {
|
||||
return a
|
||||
@@ -311,8 +355,24 @@ func CompareMapStringString(a, b map[string]string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Below is helpers for copying generic structures.
|
||||
// CopyMap creates a copy of m. Struct values are not deep copies.
|
||||
//
|
||||
// If m is nil or contains no elements, the return value is nil.
|
||||
func CopyMap[M ~map[K]V, K comparable, V any](m M) M {
|
||||
if len(m) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := make(M, len(m))
|
||||
for k, v := range m {
|
||||
result[k] = v
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// CopyMapStringString creates a copy of m.
|
||||
//
|
||||
// Deprecated; use CopyMap instead.
|
||||
func CopyMapStringString(m map[string]string) map[string]string {
|
||||
l := len(m)
|
||||
if l == 0 {
|
||||
@@ -326,6 +386,9 @@ func CopyMapStringString(m map[string]string) map[string]string {
|
||||
return c
|
||||
}
|
||||
|
||||
// CopyMapStringStruct creates a copy of m.
|
||||
//
|
||||
// Deprecated; use CopyMap instead.
|
||||
func CopyMapStringStruct(m map[string]struct{}) map[string]struct{} {
|
||||
l := len(m)
|
||||
if l == 0 {
|
||||
@@ -339,6 +402,9 @@ func CopyMapStringStruct(m map[string]struct{}) map[string]struct{} {
|
||||
return c
|
||||
}
|
||||
|
||||
// CopyMapStringInterface creates a copy of m.
|
||||
//
|
||||
// Deprecated; use CopyMap instead.
|
||||
func CopyMapStringInterface(m map[string]interface{}) map[string]interface{} {
|
||||
l := len(m)
|
||||
if l == 0 {
|
||||
@@ -375,6 +441,9 @@ func MergeMapStringString(m map[string]string, n map[string]string) map[string]s
|
||||
return result
|
||||
}
|
||||
|
||||
// CopyMapStringInt creates a copy of m.
|
||||
//
|
||||
// Deprecated; use CopyMap instead.
|
||||
func CopyMapStringInt(m map[string]int) map[string]int {
|
||||
l := len(m)
|
||||
if l == 0 {
|
||||
@@ -388,6 +457,9 @@ func CopyMapStringInt(m map[string]int) map[string]int {
|
||||
return c
|
||||
}
|
||||
|
||||
// CopyMapStringFloat64 creates a copy of m.
|
||||
//
|
||||
// Deprecated; use CopyMap instead.
|
||||
func CopyMapStringFloat64(m map[string]float64) map[string]float64 {
|
||||
l := len(m)
|
||||
if l == 0 {
|
||||
@@ -401,6 +473,9 @@ func CopyMapStringFloat64(m map[string]float64) map[string]float64 {
|
||||
return c
|
||||
}
|
||||
|
||||
// CopyMapStringSliceString creates a copy of m.
|
||||
//
|
||||
// todo: a deep value copy version of CopyMap.
|
||||
func CopyMapStringSliceString(m map[string][]string) map[string][]string {
|
||||
l := len(m)
|
||||
if l == 0 {
|
||||
@@ -414,6 +489,9 @@ func CopyMapStringSliceString(m map[string][]string) map[string][]string {
|
||||
return c
|
||||
}
|
||||
|
||||
// CopySliceString creates a copy of s.
|
||||
//
|
||||
// Deprecated; use slices.Clone instead.
|
||||
func CopySliceString(s []string) []string {
|
||||
l := len(s)
|
||||
if l == 0 {
|
||||
@@ -425,6 +503,9 @@ func CopySliceString(s []string) []string {
|
||||
return c
|
||||
}
|
||||
|
||||
// CopySliceInt creates a copy of s.
|
||||
//
|
||||
// Deprecated; use slices.Clone instead.
|
||||
func CopySliceInt(s []int) []int {
|
||||
l := len(s)
|
||||
if l == 0 {
|
||||
|
||||
@@ -8,9 +8,78 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/shoenig/test/must"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_Min(t *testing.T) {
|
||||
t.Run("int", func(t *testing.T) {
|
||||
a := 1
|
||||
b := 2
|
||||
must.Eq(t, 1, Min(a, b))
|
||||
must.Eq(t, 1, Min(b, a))
|
||||
})
|
||||
|
||||
t.Run("float64", func(t *testing.T) {
|
||||
a := 1.1
|
||||
b := 2.2
|
||||
must.Eq(t, 1.1, Min(a, b))
|
||||
must.Eq(t, 1.1, Min(b, a))
|
||||
})
|
||||
|
||||
t.Run("string", func(t *testing.T) {
|
||||
a := "cat"
|
||||
b := "dog"
|
||||
must.Eq(t, "cat", Min(a, b))
|
||||
must.Eq(t, "cat", Min(b, a))
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Max(t *testing.T) {
|
||||
t.Run("int", func(t *testing.T) {
|
||||
a := 1
|
||||
b := 2
|
||||
must.Eq(t, 2, Max(a, b))
|
||||
must.Eq(t, 2, Max(b, a))
|
||||
})
|
||||
|
||||
t.Run("float64", func(t *testing.T) {
|
||||
a := 1.1
|
||||
b := 2.2
|
||||
must.Eq(t, 2.2, Max(a, b))
|
||||
must.Eq(t, 2.2, Max(b, a))
|
||||
})
|
||||
|
||||
t.Run("string", func(t *testing.T) {
|
||||
a := "cat"
|
||||
b := "dog"
|
||||
must.Eq(t, "dog", Max(a, b))
|
||||
must.Eq(t, "dog", Max(b, a))
|
||||
})
|
||||
}
|
||||
|
||||
func Test_CopyMap(t *testing.T) {
|
||||
t.Run("nil", func(t *testing.T) {
|
||||
var m map[string]int
|
||||
result := CopyMap(m)
|
||||
must.Nil(t, result)
|
||||
})
|
||||
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
m := make(map[string]int, 10)
|
||||
result := CopyMap(m)
|
||||
must.Nil(t, result)
|
||||
})
|
||||
|
||||
t.Run("elements", func(t *testing.T) {
|
||||
m := map[string]int{"a": 1, "b": 2}
|
||||
result := CopyMap(m)
|
||||
result["a"] = -1
|
||||
must.MapEq(t, map[string]int{"a": -1, "b": 2}, result)
|
||||
must.MapEq(t, map[string]int{"a": 1, "b": 2}, m) // not modified
|
||||
})
|
||||
}
|
||||
|
||||
func TestSliceStringIsSubset(t *testing.T) {
|
||||
l := []string{"a", "b", "c"}
|
||||
s := []string{"d"}
|
||||
|
||||
7
helper/pointer/pointer.go
Normal file
7
helper/pointer/pointer.go
Normal file
@@ -0,0 +1,7 @@
|
||||
// Package pointer provides helper functions related to Go pointers.
|
||||
package pointer
|
||||
|
||||
// Of returns a pointer to a.
|
||||
func Of[A any](a A) *A {
|
||||
return &a
|
||||
}
|
||||
18
helper/pointer/pointer_test.go
Normal file
18
helper/pointer/pointer_test.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package pointer
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/shoenig/test/must"
|
||||
)
|
||||
|
||||
func Test_Of(t *testing.T) {
|
||||
s := "hello"
|
||||
sPtr := Of(s)
|
||||
|
||||
must.Eq(t, s, *sPtr)
|
||||
|
||||
b := "bye"
|
||||
sPtr = &b
|
||||
must.NotEq(t, s, *sPtr)
|
||||
}
|
||||
Reference in New Issue
Block a user