Skip to content
This repository has been archived by the owner on Dec 5, 2024. It is now read-only.

Commit

Permalink
Reduce dependencies on stringset (gopasspw#2450)
Browse files Browse the repository at this point in the history
See gopasspw#2441

Signed-off-by: Dominik Schulz <[email protected]>

Signed-off-by: Dominik Schulz <[email protected]>
  • Loading branch information
dominikschulz authored Dec 7, 2022
1 parent a5e2392 commit 02f9b17
Show file tree
Hide file tree
Showing 7 changed files with 462 additions and 18 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,5 @@ workdir/

.vscode/
NOTICE.new

debian/
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module github.com/gopasspw/gopass
go 1.18

require (
bitbucket.org/creachadair/stringset v0.0.10
filippo.io/age v1.0.0
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4
github.com/atotto/clipboard v0.1.4
Expand Down
3 changes: 0 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
bitbucket.org/creachadair/stringset v0.0.10 h1:DZjkR57sJGMycZNVVbl+26bK7vW1kwLQE6qWICWLteI=
bitbucket.org/creachadair/stringset v0.0.10/go.mod h1:6G0fsnHFxynEdWpihfZf44lnBPpTW6nkrcxITVTBHus=
filippo.io/age v1.0.0 h1:V6q14n0mqYU3qKFkZ6oOaF9oXneOviS3ubXsSVBRSzc=
filippo.io/age v1.0.0/go.mod h1:PaX+Si/Sd5G8LgfCwldsSba3H1DDQZhIhFGkhbHaBq8=
filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek=
filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 h1:ra2OtmuW0AE5csawV4YXMNGNQQXvLRps3z2Z59OPO+I=
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0=
Expand Down
6 changes: 3 additions & 3 deletions internal/action/clone.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import (
"path/filepath"
"strings"

"bitbucket.org/creachadair/stringset"
"github.com/gopasspw/gopass/internal/action/exit"
"github.com/gopasspw/gopass/internal/backend"
"github.com/gopasspw/gopass/internal/backend/crypto/age"
"github.com/gopasspw/gopass/internal/backend/crypto/gpg"
"github.com/gopasspw/gopass/internal/config"
"github.com/gopasspw/gopass/internal/cui"
"github.com/gopasspw/gopass/internal/out"
"github.com/gopasspw/gopass/internal/set"
"github.com/gopasspw/gopass/internal/store/root"
"github.com/gopasspw/gopass/pkg/ctxutil"
"github.com/gopasspw/gopass/pkg/debug"
Expand Down Expand Up @@ -195,15 +195,15 @@ func (s *Action) cloneCheckDecryptionKeys(ctx context.Context, mount string) err

debug.Log("We have useable private keys")

recpSet := stringset.New(s.Store.ListRecipients(ctx, mount)...)
recpSet := set.New(s.Store.ListRecipients(ctx, mount)...)
ids, err := crypto.ListIdentities(ctx)
if err != nil {
out.Warningf(ctx, "Failed to check decryption keys: %s", err)

return nil
}

idSet := stringset.New(ids...)
idSet := set.New(ids...)
if idSet.IsSubset(recpSet) {
out.Noticef(ctx, "Found valid decryption keys. You can now decrypt your passwords.")

Expand Down
22 changes: 11 additions & 11 deletions internal/backend/storage/fossilfs/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import (
"context"
"strings"

"bitbucket.org/creachadair/stringset"
"github.com/gopasspw/gopass/internal/set"
)

type fossilStatus struct {
Extra stringset.Set
Added stringset.Set
Edited stringset.Set
Unchanged stringset.Set
Extra set.Set[string]
Added set.Set[string]
Edited set.Set[string]
Unchanged set.Set[string]
}

func (f *Fossil) getStatus(ctx context.Context) (fossilStatus, error) {
Expand All @@ -21,10 +21,10 @@ func (f *Fossil) getStatus(ctx context.Context) (fossilStatus, error) {
}

s := fossilStatus{
Extra: stringset.New(),
Added: stringset.New(),
Edited: stringset.New(),
Unchanged: stringset.New(),
Extra: set.New[string](),
Added: set.New[string](),
Edited: set.New[string](),
Unchanged: set.New[string](),
}
for _, line := range strings.Split(string(stdout), "\n") {
op, file, found := strings.Cut(line, " ")
Expand All @@ -46,10 +46,10 @@ func (f *Fossil) getStatus(ctx context.Context) (fossilStatus, error) {
return s, nil
}

func (fs *fossilStatus) Untracked() stringset.Set {
func (fs *fossilStatus) Untracked() set.Set[string] {
return fs.Extra.Union(fs.Added).Union(fs.Edited)
}

func (fs *fossilStatus) Staged() stringset.Set {
func (fs *fossilStatus) Staged() set.Set[string] {
return fs.Edited.Union(fs.Added)
}
237 changes: 237 additions & 0 deletions internal/set/set.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
package set

import (
"fmt"
"strings"

"golang.org/x/exp/constraints"
)

// Set is a generic set type.
type Set[K constraints.Ordered] map[K]bool

// New initializes a new Set with the given elements.
func New[K constraints.Ordered](elems ...K) Set[K] {
s := make(map[K]bool, len(elems))

for _, e := range elems {
s[e] = true
}

return s
}

// String returns a string representation of the set.
func (s Set[K]) String() string {
if s.Empty() {
return "ø"
}
elems := make([]string, len(s))
for i, e := range s.Elements() {
elems[i] = fmt.Sprintf("%v", e)
}

return fmt.Sprintf("{%s}", strings.Join(elems, ", "))
}

// Elements returns the elements of the set in
// sorted order.
func (s Set[K]) Elements() []K {
return SortedKeys(s)
}

// Empty returns true if the set is empty.
func (s Set[K]) Empty() bool {
return len(s) == 0
}

// Len returns the length of the set.
func (s Set[K]) Len() int {
return len(s)
}

// Clone creates a copy of the set.
func (s Set[K]) Clone() Set[K] {
c := Set[K]{}
c.Update(s)

return c
}

// Update adds all elements from s2 to the set.
func (s *Set[K]) Update(s2 Set[K]) bool {
il := len(*s)
if *s == nil && len(s2) > 0 {
*s = make(Set[K], len(s2))
}
for k := range s2 {
(*s)[k] = true
}

return len(*s) != il
}

// Equals returns true if s and s2 contain
// exactly the same elements.
func (s Set[K]) Equals(s2 Set[K]) bool {
return len(s) == len(s2) && s.IsSubset(s2)
}

// IsSubset returns true if all elements of s
// are contained in s2.
func (s Set[K]) IsSubset(s2 Set[K]) bool {
if s.Empty() {
return true
}
if len(s) > len(s2) {
return false
}

for k := range s {
if !s2[k] {
return false
}
}

return true
}

// Union returns a new set containing all elements from
// s and s2.
func (s Set[K]) Union(s2 Set[K]) Set[K] {
if s.Empty() {
return s2
}
if s2.Empty() {
return s
}

set := make(Set[K])
for k := range s {
set[k] = true
}
for k := range s2 {
set[k] = true
}

return set
}

// Add adds the given elements to the set.
func (s *Set[K]) Add(elems ...K) bool {
il := len(*s)
if *s == nil {
*s = make(Set[K])
}
for _, k := range elems {
(*s)[k] = true
}

return len(*s) != il
}

// Remove deletes the given element from the set.
func (s Set[K]) Remove(s2 Set[K]) bool {
if s.Empty() {
return false
}
il := len(s)
for k := range s2 {
delete(s, k)
}

return len(s) != il
}

// Discard deletes the given elements from the set.
func (s Set[K]) Discard(elems ...K) bool {
if s.Empty() {
return false
}
il := len(s)
for _, e := range elems {
delete(s, e)
}

return len(s) != il
}

// Map returns a new set by applied the function f
// to all it's elements.
func (s Set[K]) Map(f func(K) K) Set[K] {
out := make(Set[K], len(s))
for k := range s {
out.Add(f(k))
}

return out
}

// Each applies the function f to all it's elements.
func (s Set[K]) Each(f func(K)) {
for k := range s {
f(k)
}
}

// Select returns a new set with all the elements for
// that f returns true.
func (s Set[K]) Select(f func(K) bool) Set[K] {
out := make(Set[K], len(s))
for k := range s {
if f(k) {
out.Add(k)
}
}

return out
}

// Partition returns two new sets: the first contains all
// the elements for which f returns true. The seconds the others.
func (s Set[K]) Partition(f func(K) bool) (Set[K], Set[K]) {
yes := make(Set[K], len(s))
no := make(Set[K], len(s))
for k := range s {
if f(k) {
yes.Add(k)

continue
}

no.Add(k)
}

return yes, no
}

// Choose returns the first element for which f returns true.
func (s Set[K]) Choose(f func(K) bool) (K, bool) {
if f == nil {
for k := range s {
return k, true
}
}
for k := range s {
if f(k) {
return k, true
}
}

var zero K

return zero, false
}

// Count returns the number of elements for which f returns true.
func (s Set[K]) Count(f func(K) bool) int {
n := 0

for k := range s {
if f(k) {
n++
}
}

return n
}
Loading

0 comments on commit 02f9b17

Please sign in to comment.