mirror of
https://github.com/anchore/syft.git
synced 2026-11-01 23:16:30 +01:00
Add relationships for python poetry packages (#2906)
* [wip] add initial poetry.lock relationship support Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * provide generic set for basic types Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * dependency resolver should allow for conditional deps Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * add tests for poetry lock relationship additions Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * update schema with python poetry dependency refs Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * dep specification data structure should not be recursive in nature Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> --------- Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
@@ -3,5 +3,5 @@ package internal
|
||||
const (
|
||||
// JSONSchemaVersion is the current schema version output by the JSON encoder
|
||||
// This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment.
|
||||
JSONSchemaVersion = "16.0.12"
|
||||
JSONSchemaVersion = "16.0.13"
|
||||
)
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Set represents a generic set type.
|
||||
type Set[T comparable] map[T]struct{}
|
||||
|
||||
// NewSet creates a new empty Set.
|
||||
func NewSet[T comparable](start ...T) Set[T] {
|
||||
ret := make(Set[T])
|
||||
for _, v := range start {
|
||||
ret.Add(v)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Add adds elements to the set.
|
||||
func (s Set[T]) Add(elements ...T) {
|
||||
for _, e := range elements {
|
||||
s[e] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove removes an element from the set.
|
||||
func (s Set[T]) Remove(element T) {
|
||||
delete(s, element)
|
||||
}
|
||||
|
||||
// Contains checks if an element is in the set.
|
||||
func (s Set[T]) Contains(element T) bool {
|
||||
_, ok := s[element]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ToSlice returns a sorted slice of elements in the set.
|
||||
func (s Set[T]) ToSlice() []T {
|
||||
ret := make([]T, len(s))
|
||||
idx := 0
|
||||
for v := range s {
|
||||
ret[idx] = v
|
||||
idx++
|
||||
}
|
||||
sort.Slice(ret, func(i, j int) bool {
|
||||
return fmt.Sprintf("%v", ret[i]) < fmt.Sprintf("%v", ret[j])
|
||||
})
|
||||
return ret
|
||||
}
|
||||
|
||||
// Equals checks if two sets are equal.
|
||||
func (s Set[T]) Equals(o Set[T]) bool {
|
||||
if len(s) != len(o) {
|
||||
return false
|
||||
}
|
||||
for k := range s {
|
||||
if !o.Contains(k) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Empty checks if the set is empty.
|
||||
func (s Set[T]) Empty() bool {
|
||||
return len(s) == 0
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNewSet(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
start []int
|
||||
result Set[int]
|
||||
}{
|
||||
{"empty set", []int{}, NewSet[int]()},
|
||||
{"non-empty set", []int{1, 2, 3}, NewSet(1, 2, 3)},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := NewSet(tt.start...)
|
||||
require.Equal(t, tt.result, s)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdd(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input []int
|
||||
add []int
|
||||
result Set[int]
|
||||
}{
|
||||
{"add to empty set", []int{}, []int{1, 2, 3}, NewSet(1, 2, 3)},
|
||||
{"add to non-empty set", []int{1}, []int{2, 3}, NewSet(1, 2, 3)},
|
||||
{"add existing elements", []int{1, 2}, []int{2, 3}, NewSet(1, 2, 3)},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := NewSet(tt.input...)
|
||||
s.Add(tt.add...)
|
||||
assert.Equal(t, tt.result, s)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemove(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input []int
|
||||
remove int
|
||||
result Set[int]
|
||||
}{
|
||||
{"remove from non-empty set", []int{1, 2, 3}, 2, NewSet(1, 3)},
|
||||
{"remove non-existent element", []int{1, 2}, 3, NewSet(1, 2)},
|
||||
{"remove from single-element set", []int{1}, 1, NewSet[int]()},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := NewSet(tt.input...)
|
||||
s.Remove(tt.remove)
|
||||
assert.Equal(t, tt.result, s)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestContains(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input []int
|
||||
contains int
|
||||
result bool
|
||||
}{
|
||||
{"element in set", []int{1, 2, 3}, 2, true},
|
||||
{"element not in set", []int{1, 2}, 3, false},
|
||||
{"empty set", []int{}, 1, false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := NewSet(tt.input...)
|
||||
assert.Equal(t, tt.result, s.Contains(tt.contains))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestToSlice(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input []int
|
||||
result []int
|
||||
}{
|
||||
{"non-empty set", []int{3, 1, 2}, []int{1, 2, 3}},
|
||||
{"empty set", []int{}, []int{}},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := NewSet(tt.input...)
|
||||
assert.Equal(t, tt.result, s.ToSlice())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEquals(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
set1 []int
|
||||
set2 []int
|
||||
result bool
|
||||
}{
|
||||
{"equal sets", []int{1, 2, 3}, []int{3, 2, 1}, true},
|
||||
{"different sets", []int{1, 2}, []int{2, 3}, false},
|
||||
{"empty sets", []int{}, []int{}, true},
|
||||
{"one empty set", []int{1, 2}, []int{}, false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s1 := NewSet(tt.set1...)
|
||||
s2 := NewSet(tt.set2...)
|
||||
assert.Equal(t, tt.result, s1.Equals(s2))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmpty(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input []int
|
||||
result bool
|
||||
}{
|
||||
{"non-empty set", []int{1}, false},
|
||||
{"empty set", []int{}, true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := NewSet(tt.input...)
|
||||
assert.Equal(t, tt.result, s.Empty())
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package internal
|
||||
|
||||
import "sort"
|
||||
|
||||
// StringSet represents a set of string types.
|
||||
type StringSet map[string]struct{}
|
||||
|
||||
// NewStringSet creates a new empty StringSet.
|
||||
func NewStringSet(start ...string) StringSet {
|
||||
ret := make(StringSet)
|
||||
for _, s := range start {
|
||||
ret.Add(s)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Add a string to the set.
|
||||
func (s StringSet) Add(i ...string) {
|
||||
for _, str := range i {
|
||||
s[str] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove a string from the set.
|
||||
func (s StringSet) Remove(i string) {
|
||||
delete(s, i)
|
||||
}
|
||||
|
||||
// Contains indicates if the given string is contained within the set.
|
||||
func (s StringSet) Contains(i string) bool {
|
||||
_, ok := s[i]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ToSlice returns a sorted slice of strings that are contained within the set.
|
||||
func (s StringSet) ToSlice() []string {
|
||||
ret := make([]string, len(s))
|
||||
idx := 0
|
||||
for v := range s {
|
||||
ret[idx] = v
|
||||
idx++
|
||||
}
|
||||
sort.Strings(ret)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s StringSet) Equals(o StringSet) bool {
|
||||
if len(s) != len(o) {
|
||||
return false
|
||||
}
|
||||
for k := range s {
|
||||
if !o.Contains(k) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s StringSet) Empty() bool {
|
||||
return len(s) < 1
|
||||
}
|
||||
Reference in New Issue
Block a user