Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functionality to slicesext #2619

Merged
merged 3 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 2 additions & 2 deletions private/buf/bufwire/module_config_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,8 @@ func (m *moduleConfigReader) getProtoFileModuleSourceConfigSet(
if err != nil {
return nil, err
}
workspaceConfigs := slicesext.ToMap(bufwork.AllConfigFilePaths)
moduleConfigs := slicesext.ToMap(bufconfig.AllConfigFilePaths)
workspaceConfigs := slicesext.ToStructMap(bufwork.AllConfigFilePaths)
moduleConfigs := slicesext.ToStructMap(bufconfig.AllConfigFilePaths)
terminateFileProvider := readBucketCloser.TerminateFileProvider()
var workspaceConfigDirectory string
var moduleConfigDirectory string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ func run(
container.Logger(),
flags.Origin,
clientTLSConfig,
slicesext.ToMap(flags.DisallowedHeaders),
slicesext.ToStructMap(flags.DisallowedHeaders),
flags.ForwardHeaders,
flags.PrivateNetwork,
)
Expand Down
4 changes: 2 additions & 2 deletions private/bufpkg/bufimage/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func imageWithOnlyPaths(image Image, fileOrDirPaths []string, excludeFileOrDirPa
if err := normalpath.ValidatePathsNormalizedValidatedUnique(excludeFileOrDirPaths); err != nil {
return nil, err
}
excludeFileOrDirPathMap := slicesext.ToMap(excludeFileOrDirPaths)
excludeFileOrDirPathMap := slicesext.ToStructMap(excludeFileOrDirPaths)
// These are the files that fileOrDirPaths actually reference and will
// result in the non-imports in our resulting Image. The Image will also include
// the ImageFiles that the nonImportImageFiles import
Expand Down Expand Up @@ -132,7 +132,7 @@ func imageWithOnlyPaths(image Image, fileOrDirPaths []string, excludeFileOrDirPa
// make a map of the directory paths
// note that we do not make this a map to begin with as maps are unordered,
// and we want to make sure we iterate over the paths in a deterministic order
potentialDirPathMap := slicesext.ToMap(potentialDirPaths)
potentialDirPathMap := slicesext.ToStructMap(potentialDirPaths)

// map of all paths based on the imageFiles
// the map of paths within potentialDirPath that matches a file in image.Files()
Expand Down
2 changes: 1 addition & 1 deletion private/bufpkg/bufmodule/bufmoduleconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func newConfigV1Beta1(externalConfig ExternalConfigV1Beta1, deps ...string) (*Co
}

// verify that all excludes are within a root
rootMap := slicesext.ToMap(roots)
rootMap := slicesext.ToStructMap(roots)
for _, fullExclude := range fullExcludes {
switch matchingRoots := normalpath.MapAllEqualOrContainingPaths(rootMap, fullExclude, normalpath.Relative); len(matchingRoots) {
case 0:
Expand Down
4 changes: 2 additions & 2 deletions private/bufpkg/bufmodule/targeting_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (m *targetingModule) TargetFileInfos(ctx context.Context) (fileInfos []bufm
bufmoduleref.SortFileInfos(fileInfos)
}
}()
excludePathMap := slicesext.ToMap(m.excludePaths)
excludePathMap := slicesext.ToStructMap(m.excludePaths)
// We start by ensuring that no paths have been duplicated between target and exclude pathes.
for _, targetPath := range m.targetPaths {
if _, ok := excludePathMap[targetPath]; ok {
Expand Down Expand Up @@ -150,7 +150,7 @@ func (m *targetingModule) TargetFileInfos(ctx context.Context) (fileInfos []bufm
}
// We have potential directory paths, do the expensive operation to
// make a map of the directory paths.
potentialDirPathMap := slicesext.ToMap(potentialDirPaths)
potentialDirPathMap := slicesext.ToStructMap(potentialDirPaths)
// The map of paths within potentialDirPath that matches a file.
// This needs to contain all paths in potentialDirPathMap at the end for us to
// have had matches for every targetPath input.
Expand Down
4 changes: 2 additions & 2 deletions private/pkg/bandeps/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func (s *state) packagesForPackageExpressionUncached(
span.SetStatus(codes.Error, err.Error())
return nil, err
}
return slicesext.ToMap(getNonEmptyLines(string(data))), nil
return slicesext.ToStructMap(getNonEmptyLines(string(data))), nil
}

func (s *state) depsForPackage(
Expand Down Expand Up @@ -234,7 +234,7 @@ func (s *state) depsForPackageUncached(
span.SetStatus(codes.Error, err.Error())
return nil, err
}
return slicesext.ToMap(getNonEmptyLines(string(data))), nil
return slicesext.ToStructMap(getNonEmptyLines(string(data))), nil
}

type packagesResult struct {
Expand Down
2 changes: 1 addition & 1 deletion private/pkg/git/lister.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (l *lister) ListFilesAndUnstagedFiles(

// stringSliceExcept returns all elements in source that are not in except.
func stringSliceExcept(source []string, except []string) []string {
exceptMap := slicesext.ToMap(except)
exceptMap := slicesext.ToStructMap(except)
result := make([]string, 0, len(source))
for _, s := range source {
if _, ok := exceptMap[s]; !ok {
Expand Down
8 changes: 4 additions & 4 deletions private/pkg/normalpath/normalpath_unix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ func TestMapHasEqualOrContainingPath(t *testing.T) {
}

func testMapHasEqualOrContainingPath(t *testing.T, expected bool, path string, keys ...string) {
keyMap := slicesext.ToMap(keys)
keyMap := slicesext.ToStructMap(keys)
assert.Equal(t, expected, MapHasEqualOrContainingPath(keyMap, path, Relative), fmt.Sprintf("%s %v", path, keys))
}

Expand All @@ -367,7 +367,7 @@ func testMapAllEqualOrContainingPaths(t *testing.T, expected []string, path stri
expected = make([]string, 0)
}
sort.Strings(expected)
keyMap := slicesext.ToMap(keys)
keyMap := slicesext.ToStructMap(keys)
assert.Equal(t, expected, MapAllEqualOrContainingPaths(keyMap, path, Relative), fmt.Sprintf("%s %v", path, keys))
}

Expand Down Expand Up @@ -424,7 +424,7 @@ func TestMapHasEqualOrContainingPathAbs(t *testing.T) {
}

func testMapHasEqualOrContainingPathAbs(t *testing.T, expected bool, path string, keys ...string) {
keyMap := slicesext.ToMap(keys)
keyMap := slicesext.ToStructMap(keys)
assert.Equal(t, expected, MapHasEqualOrContainingPath(keyMap, path, Absolute), fmt.Sprintf("%s %v", path, keys))
}

Expand All @@ -449,6 +449,6 @@ func testMapAllEqualOrContainingPathsAbs(t *testing.T, expected []string, path s
expected = make([]string, 0)
}
sort.Strings(expected)
keyMap := slicesext.ToMap(keys)
keyMap := slicesext.ToStructMap(keys)
assert.Equal(t, expected, MapAllEqualOrContainingPaths(keyMap, path, Absolute), fmt.Sprintf("%s %v", path, keys))
}
8 changes: 4 additions & 4 deletions private/pkg/normalpath/normalpath_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ func TestMapHasEqualOrContainingPath(t *testing.T) {
}

func testMapHasEqualOrContainingPath(t *testing.T, expected bool, path string, keys ...string) {
keyMap := slicesext.ToMap(keys)
keyMap := slicesext.ToStructMap(keys)
assert.Equal(t, expected, MapHasEqualOrContainingPath(keyMap, path, Relative), fmt.Sprintf("%s %v", path, keys))
}

Expand All @@ -386,7 +386,7 @@ func testMapAllEqualOrContainingPaths(t *testing.T, expected []string, path stri
expected = make([]string, 0)
}
sort.Strings(expected)
keyMap := slicesext.ToMap(keys)
keyMap := slicesext.ToStructMap(keys)
assert.Equal(t, expected, MapAllEqualOrContainingPaths(keyMap, path, Relative), fmt.Sprintf("%s %v", path, keys))
}

Expand Down Expand Up @@ -497,7 +497,7 @@ func TestMapHasEqualOrContainingPathAbs(t *testing.T) {
}

func testMapHasEqualOrContainingPathAbs(t *testing.T, expected bool, path string, keys ...string) {
keyMap := slicesext.ToMap(keys)
keyMap := slicesext.ToStructMap(keys)
assert.Equal(t, expected, MapHasEqualOrContainingPath(keyMap, path, Absolute), fmt.Sprintf("%s %v", path, keys))
}

Expand Down Expand Up @@ -527,6 +527,6 @@ func testMapAllEqualOrContainingPathsAbs(t *testing.T, expected []string, path s
expected = make([]string, 0)
}
sort.Strings(expected)
keyMap := slicesext.ToMap(keys)
keyMap := slicesext.ToStructMap(keys)
assert.Equal(t, expected, MapAllEqualOrContainingPaths(keyMap, path, Absolute), fmt.Sprintf("%s %v", path, keys))
}
36 changes: 32 additions & 4 deletions private/pkg/slicesext/slicesext.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,26 @@ func Copy[T any](s []T) []T {
return sc
}

// ToMap converts the slice to a map.
func ToMap[T comparable](s []T) map[T]struct{} {
// ToStructMap converts the slice to a map with struct{} values.
func ToStructMap[T comparable](s []T) map[T]struct{} {
m := make(map[T]struct{}, len(s))
for _, e := range s {
m[e] = struct{}{}
}
return m
}

// ToValuesMap transforms the input slice into a map from f(V) -> V.
//
// Duplicate values of type K will result in a single map entry.
func ToValuesMapV[K comparable, V any](s []V, f func(V) K) map[K]V {
m := make(map[K]V)
for _, e := range s {
m[f(e)] = e
}
return m
}

// MapKeysToSortedSlice converts the map's keys to a sorted slice.
func MapKeysToSortedSlice[M ~map[K]V, K Ordered, V any](m M) []K {
s := MapKeysToSlice(m)
Expand All @@ -171,7 +182,24 @@ func MapKeysToSlice[K comparable, V any](m map[K]V) []K {

// ToUniqueSorted returns a sorted copy of s with no duplicates.
func ToUniqueSorted[S ~[]T, T Ordered](s S) S {
return MapKeysToSortedSlice(ToMap(s))
return MapKeysToSortedSlice(ToStructMap(s))
}

// Duplicates returns the duplicate values in s.
//
// Values are returned in the order they are found in S.
func Duplicates[T comparable](s []T) []T {
count := make(map[T]int, len(s))
// Needed instead of var declaration to make tests pass.
duplicates := make([]T, 0)
for _, e := range s {
count[e] = count[e] + 1
if count[e] == 2 {
// Only insert the first time this is found.
duplicates = append(duplicates, e)
}
}
return duplicates
}

// ToChunks splits s into chunks of the given chunk size.
Expand Down Expand Up @@ -214,7 +242,7 @@ func ElementsEqual[T comparable](one []T, two []T) bool {
//
// Nil and empty slices are treated as equals.
func ElementsContained(superset []string, subset []string) bool {
m := ToMap(superset)
m := ToStructMap(superset)
for _, elem := range subset {
if _, ok := m[elem]; !ok {
return false
Expand Down
24 changes: 24 additions & 0 deletions private/pkg/slicesext/slicesext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,30 @@ func TestElementsContained(t *testing.T) {
assert.False(t, ElementsContained([]string{"two"}, []string{"one", "two"}))
}

func TestDuplicates(t *testing.T) {
t.Parallel()
assert.Equal(
t,
[]string{},
Duplicates([]string{"a", "b", "c", "d", "e"}),
)
assert.Equal(
t,
[]string{"a"},
Duplicates([]string{"a", "b", "c", "a", "e"}),
)
assert.Equal(
t,
[]string{"a"},
Duplicates([]string{"a", "a", "c", "a", "e"}),
)
assert.Equal(
t,
[]string{"b", "a"},
Duplicates([]string{"a", "b", "b", "a", "e"}),
)
}

func TestToChunks(t *testing.T) {
t.Parallel()
testToChunks(
Expand Down
6 changes: 3 additions & 3 deletions private/pkg/stringutil/stringutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ func MapToSlice(m map[string]struct{}) []string {

// SliceToMap transforms s to a map.
//
// Deprecated: Use slicesext.ToMap instead.
// Deprecated: Use slicesext.ToStructMap instead.
func SliceToMap(s []string) map[string]struct{} {
return slicesext.ToMap(s)
return slicesext.ToStructMap(s)
}

// SliceToUniqueSortedSlice returns a sorted copy of s with no duplicates.
Expand All @@ -88,7 +88,7 @@ func SliceToUniqueSortedSlice(s []string) []string {
//
// Strings with only spaces are considered empty.
func SliceToUniqueSortedSliceFilterEmptyStrings(s []string) []string {
m := slicesext.ToMap(s)
m := slicesext.ToStructMap(s)
for key := range m {
if strings.TrimSpace(key) == "" {
delete(m, key)
Expand Down