Skip to content

Commit 7417994

Browse files
authored
Merge pull request #419 from docker/client/list-plugins
feat(client): list plugins method
2 parents 5823d51 + b7198a1 commit 7417994

5 files changed

Lines changed: 281 additions & 4 deletions

File tree

client/client.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,16 @@ type config struct {
7575

7676
type client struct {
7777
resolverClient resolverv1connect.ResolverServiceClient
78+
listClient resolverv1connect.ListServiceClient
7879
}
7980

80-
func New(options ...Option) (secrets.Resolver, error) {
81+
type Client interface {
82+
secrets.Resolver
83+
84+
ListPlugins(ctx context.Context) ([]PluginInfo, error)
85+
}
86+
87+
func New(options ...Option) (Client, error) {
8188
cfg := &config{
8289
requestTimeout: api.DefaultClientRequestTimeout,
8390
}
@@ -112,6 +119,7 @@ func New(options ...Option) (secrets.Resolver, error) {
112119
}
113120
return &client{
114121
resolverClient: resolverv1connect.NewResolverServiceClient(c, "http://unix"),
122+
listClient: resolverv1connect.NewListServiceClient(c, "http://unix"),
115123
}, nil
116124
}
117125

@@ -147,6 +155,43 @@ func (c client) GetSecrets(ctx context.Context, pattern secrets.Pattern) ([]secr
147155
return envelopes, nil
148156
}
149157

158+
func (c client) ListPlugins(ctx context.Context) ([]PluginInfo, error) {
159+
req := connect.NewRequest(v1.ListPluginsRequest_builder{}.Build())
160+
resp, err := c.listClient.ListPlugins(ctx, req)
161+
if err != nil {
162+
return nil, err
163+
}
164+
var result []PluginInfo
165+
for _, item := range resp.Msg.GetPlugins() {
166+
name, err := api.NewName(item.GetName())
167+
if err != nil {
168+
continue
169+
}
170+
version, err := api.NewVersion(item.GetVersion())
171+
if err != nil {
172+
continue
173+
}
174+
pattern, err := secrets.ParsePattern(item.GetPattern())
175+
if err != nil {
176+
continue
177+
}
178+
result = append(result, PluginInfo{
179+
Name: name,
180+
Version: version,
181+
Pattern: pattern,
182+
External: item.GetExternal(),
183+
})
184+
}
185+
return result, nil
186+
}
187+
188+
type PluginInfo struct {
189+
Name api.Name
190+
Version api.Version
191+
Pattern secrets.Pattern
192+
External bool
193+
}
194+
150195
func dialFromPath(path string) dial {
151196
return func(ctx context.Context, _, _ string) (net.Conn, error) {
152197
d := &net.Dialer{}

client/client_test.go

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
package client
2+
3+
import (
4+
"context"
5+
"net"
6+
"net/http"
7+
"os"
8+
"path/filepath"
9+
"testing"
10+
"time"
11+
12+
"connectrpc.com/connect"
13+
"github.com/stretchr/testify/assert"
14+
"github.com/stretchr/testify/require"
15+
"google.golang.org/protobuf/proto"
16+
17+
"github.com/docker/secrets-engine/x/api"
18+
resolverv1 "github.com/docker/secrets-engine/x/api/resolver/v1"
19+
"github.com/docker/secrets-engine/x/api/resolver/v1/resolverv1connect"
20+
"github.com/docker/secrets-engine/x/secrets"
21+
"github.com/docker/secrets-engine/x/testhelper"
22+
)
23+
24+
var _ resolverv1connect.ListServiceHandler = &mockPluginsList{}
25+
26+
type mockPluginsList struct {
27+
list []PluginInfo
28+
}
29+
30+
func (m mockPluginsList) ListPlugins(context.Context, *connect.Request[resolverv1.ListPluginsRequest]) (*connect.Response[resolverv1.ListPluginsResponse], error) {
31+
var plugins []*resolverv1.Plugin
32+
for _, plugin := range m.list {
33+
var name string
34+
if plugin.Name != nil {
35+
name = plugin.Name.String()
36+
}
37+
var version string
38+
if plugin.Version != nil {
39+
version = plugin.Version.String()
40+
}
41+
var pattern string
42+
if plugin.Pattern != nil {
43+
pattern = plugin.Pattern.String()
44+
}
45+
plugins = append(plugins, resolverv1.Plugin_builder{
46+
Name: proto.String(name),
47+
Version: proto.String(version),
48+
Pattern: proto.String(pattern),
49+
External: proto.Bool(plugin.External),
50+
}.Build())
51+
}
52+
return connect.NewResponse(resolverv1.ListPluginsResponse_builder{
53+
Plugins: plugins,
54+
}.Build()), nil
55+
}
56+
57+
type handler struct {
58+
pattern string
59+
handler http.Handler
60+
}
61+
62+
func muxServer(t *testing.T, socketPath string, handlers []handler) {
63+
t.Helper()
64+
_ = os.Remove(socketPath)
65+
require.NoError(t, os.MkdirAll(filepath.Dir(socketPath), 0o755))
66+
listener, err := net.Listen("unix", socketPath)
67+
require.NoError(t, err)
68+
mux := http.NewServeMux()
69+
for _, h := range handlers {
70+
mux.Handle(h.pattern, h.handler)
71+
}
72+
73+
server := &http.Server{Handler: mux}
74+
75+
go func() {
76+
_ = server.Serve(listener)
77+
}()
78+
79+
t.Cleanup(func() {
80+
shutdownCtx, cancel := context.WithTimeout(t.Context(), 5*time.Second)
81+
defer cancel()
82+
83+
_ = server.Shutdown(shutdownCtx)
84+
_ = listener.Close()
85+
_ = os.RemoveAll(socketPath)
86+
})
87+
}
88+
89+
func wrapHandler(pattern string, h http.Handler) handler {
90+
return handler{pattern: pattern, handler: h}
91+
}
92+
93+
func mockListPluginsEngine(t *testing.T, plugins []PluginInfo) string {
94+
t.Helper()
95+
socketPath := testhelper.RandomShortSocketName()
96+
muxServer(t, socketPath, []handler{wrapHandler(resolverv1connect.NewListServiceHandler(&mockPluginsList{list: plugins}))})
97+
return socketPath
98+
}
99+
100+
func Test_ListPlugins(t *testing.T) {
101+
t.Parallel()
102+
t.Run("external and internal plugins", func(t *testing.T) {
103+
plugins := []PluginInfo{
104+
{
105+
Name: api.MustNewName("foo"),
106+
Version: api.MustNewVersion("v1"),
107+
Pattern: secrets.MustParsePattern("**"),
108+
},
109+
{
110+
Name: api.MustNewName("bar"),
111+
Version: api.MustNewVersion("v1"),
112+
Pattern: secrets.MustParsePattern("**"),
113+
External: true,
114+
},
115+
}
116+
socket := mockListPluginsEngine(t, plugins)
117+
client, err := New(WithSocketPath(socket))
118+
require.NoError(t, err)
119+
result, err := client.ListPlugins(t.Context())
120+
require.NoError(t, err)
121+
assert.Equal(t, plugins, result)
122+
})
123+
t.Run("no plugins", func(t *testing.T) {
124+
var plugins []PluginInfo
125+
socket := mockListPluginsEngine(t, plugins)
126+
client, err := New(WithSocketPath(socket))
127+
require.NoError(t, err)
128+
result, err := client.ListPlugins(t.Context())
129+
require.NoError(t, err)
130+
assert.Empty(t, result)
131+
})
132+
t.Run("mix of valid and invalid plugin info", func(t *testing.T) {
133+
plugins := []PluginInfo{
134+
{
135+
Name: api.MustNewName("foo"),
136+
},
137+
{
138+
Name: api.MustNewName("bar"),
139+
Version: api.MustNewVersion("v1"),
140+
Pattern: secrets.MustParsePattern("**"),
141+
},
142+
}
143+
socket := mockListPluginsEngine(t, plugins)
144+
client, err := New(WithSocketPath(socket))
145+
require.NoError(t, err)
146+
result, err := client.ListPlugins(t.Context())
147+
require.NoError(t, err)
148+
assert.Equal(t, []PluginInfo{
149+
{
150+
Name: api.MustNewName("bar"),
151+
Version: api.MustNewVersion("v1"),
152+
Pattern: secrets.MustParsePattern("**"),
153+
},
154+
}, result)
155+
})
156+
}

client/go.mod

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,34 @@ replace github.com/docker/secrets-engine/x => ../x
1010
require (
1111
connectrpc.com/connect v1.18.1
1212
github.com/docker/secrets-engine/x v0.0.12-do.not.use
13+
github.com/stretchr/testify v1.11.1
1314
google.golang.org/protobuf v1.36.8
1415
)
1516

1617
require (
17-
github.com/google/go-cmp v0.7.0 // indirect
18+
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
19+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
20+
github.com/go-logr/logr v1.4.3 // indirect
21+
github.com/go-logr/stdr v1.2.2 // indirect
22+
github.com/google/uuid v1.6.0 // indirect
23+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect
24+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
25+
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
26+
go.opentelemetry.io/otel v1.38.0 // indirect
27+
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect
28+
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect
29+
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect
30+
go.opentelemetry.io/otel/metric v1.38.0 // indirect
31+
go.opentelemetry.io/otel/sdk v1.38.0 // indirect
32+
go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
33+
go.opentelemetry.io/otel/trace v1.38.0 // indirect
34+
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
1835
golang.org/x/mod v0.26.0 // indirect
36+
golang.org/x/net v0.43.0 // indirect
37+
golang.org/x/sys v0.37.0 // indirect
38+
golang.org/x/text v0.28.0 // indirect
39+
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect
40+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect
41+
google.golang.org/grpc v1.75.0 // indirect
42+
gopkg.in/yaml.v3 v3.0.1 // indirect
1943
)

client/go.sum

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,74 @@
11
connectrpc.com/connect v1.18.1 h1:PAg7CjSAGvscaf6YZKUefjoih5Z/qYkyaTrBW8xvYPw=
22
connectrpc.com/connect v1.18.1/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8=
3+
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
4+
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
35
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
46
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
7+
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
8+
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
9+
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
10+
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
11+
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
12+
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
13+
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
514
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
615
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
16+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
17+
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
18+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU=
19+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs=
20+
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
21+
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
22+
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
23+
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
724
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
825
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
26+
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
27+
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
928
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
1029
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
30+
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
31+
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
32+
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
33+
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
34+
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8=
35+
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw=
36+
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24=
37+
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU=
38+
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54=
39+
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk=
40+
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
41+
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
42+
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
43+
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
44+
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
45+
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
46+
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
47+
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
48+
go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4=
49+
go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE=
50+
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
51+
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
1152
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
1253
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
1354
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
1455
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
56+
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
57+
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
1558
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
1659
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
60+
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
61+
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
62+
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY=
63+
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE=
64+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE=
65+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc=
66+
google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4=
67+
google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
1768
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
1869
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
70+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
71+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
72+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
1973
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
2074
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

vendor/modules.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,6 @@ github.com/go-logr/stdr
138138
# github.com/godbus/dbus/v5 v5.1.0
139139
## explicit; go 1.12
140140
github.com/godbus/dbus/v5
141-
# github.com/google/go-cmp v0.7.0
142-
## explicit; go 1.21
143141
# github.com/google/uuid v1.6.0
144142
## explicit
145143
github.com/google/uuid

0 commit comments

Comments
 (0)