Skip to content

Commit ae05085

Browse files
gystemdhacdias
andauthored
feat: enables searching pins by name (ipfs#10412)
Co-authored-by: Henrique Dias <mail@hacdias.com>
1 parent 2841ec0 commit ae05085

File tree

5 files changed

+59
-8
lines changed

5 files changed

+59
-8
lines changed

core/commands/pin/pin.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ Example:
362362
cmds.BoolOption(pinQuietOptionName, "q", "Write just hashes of objects."),
363363
cmds.BoolOption(pinStreamOptionName, "s", "Enable streaming of pins as they are discovered."),
364364
cmds.BoolOption(pinNamesOptionName, "n", "Enable displaying pin names (slower)."),
365+
cmds.StringOption(pinNameOptionName, "Display pins with names that contain the value provided (case-sensitive, exact match)."),
365366
},
366367
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
367368
api, err := cmdenv.GetApi(env, req)
@@ -372,6 +373,7 @@ Example:
372373
typeStr, _ := req.Options[pinTypeOptionName].(string)
373374
stream, _ := req.Options[pinStreamOptionName].(bool)
374375
displayNames, _ := req.Options[pinNamesOptionName].(bool)
376+
name, _ := req.Options[pinNameOptionName].(string)
375377

376378
switch typeStr {
377379
case "all", "direct", "indirect", "recursive":
@@ -397,7 +399,7 @@ Example:
397399
if len(req.Arguments) > 0 {
398400
err = pinLsKeys(req, typeStr, api, emit)
399401
} else {
400-
err = pinLsAll(req, typeStr, displayNames, api, emit)
402+
err = pinLsAll(req, typeStr, displayNames || name != "", name, api, emit)
401403
}
402404
if err != nil {
403405
return err
@@ -537,7 +539,7 @@ func pinLsKeys(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fu
537539
return nil
538540
}
539541

540-
func pinLsAll(req *cmds.Request, typeStr string, detailed bool, api coreiface.CoreAPI, emit func(value PinLsOutputWrapper) error) error {
542+
func pinLsAll(req *cmds.Request, typeStr string, detailed bool, name string, api coreiface.CoreAPI, emit func(value PinLsOutputWrapper) error) error {
541543
enc, err := cmdenv.GetCidEncoder(req)
542544
if err != nil {
543545
return err
@@ -555,7 +557,7 @@ func pinLsAll(req *cmds.Request, typeStr string, detailed bool, api coreiface.Co
555557
panic("unhandled pin type")
556558
}
557559

558-
pins, err := api.Pin().Ls(req.Context, opt, options.Pin.Ls.Detailed(detailed))
560+
pins, err := api.Pin().Ls(req.Context, opt, options.Pin.Ls.Detailed(detailed), options.Pin.Ls.Name(name))
559561
if err != nil {
560562
return err
561563
}

core/coreapi/pin.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package coreapi
33
import (
44
"context"
55
"fmt"
6+
"strings"
67

78
bserv "github.com/ipfs/boxo/blockservice"
89
offline "github.com/ipfs/boxo/exchange/offline"
@@ -67,7 +68,7 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) (<-chan c
6768
return nil, fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", settings.Type)
6869
}
6970

70-
return api.pinLsAll(ctx, settings.Type, settings.Detailed), nil
71+
return api.pinLsAll(ctx, settings.Type, settings.Detailed, settings.Name), nil
7172
}
7273

7374
func (api *PinAPI) IsPinned(ctx context.Context, p path.Path, opts ...caopts.PinIsPinnedOption) (string, bool, error) {
@@ -276,17 +277,17 @@ func (p *pinInfo) Err() error {
276277
//
277278
// The caller must keep reading results until the channel is closed to prevent
278279
// leaking the goroutine that is fetching pins.
279-
func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string, detailed bool) <-chan coreiface.Pin {
280+
func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string, detailed bool, name string) <-chan coreiface.Pin {
280281
out := make(chan coreiface.Pin, 1)
281282

282283
emittedSet := cid.NewSet()
283284

284-
AddToResultKeys := func(c cid.Cid, name, typeStr string) error {
285-
if emittedSet.Visit(c) {
285+
AddToResultKeys := func(c cid.Cid, pinName, typeStr string) error {
286+
if emittedSet.Visit(c) && (name == "" || strings.Contains(pinName, name)) {
286287
select {
287288
case out <- &pinInfo{
288289
pinType: typeStr,
289-
name: name,
290+
name: pinName,
290291
path: path.FromCid(c),
291292
}:
292293
case <-ctx.Done():

core/coreiface/options/pin.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ type PinAddSettings struct {
1212
type PinLsSettings struct {
1313
Type string
1414
Detailed bool
15+
Name string
1516
}
1617

1718
// PinIsPinnedSettings represent the settings for PinAPI.IsPinned
@@ -205,6 +206,13 @@ func (pinLsOpts) Detailed(detailed bool) PinLsOption {
205206
}
206207
}
207208

209+
func (pinLsOpts) Name(name string) PinLsOption {
210+
return func(settings *PinLsSettings) error {
211+
settings.Name = name
212+
return nil
213+
}
214+
}
215+
208216
type pinIsPinnedOpts struct{}
209217

210218
// All is an option for Pin.IsPinned which will make it search in all type of pins.

docs/changelogs/v0.29.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,18 @@
66

77
- [Overview](#overview)
88
- [🔦 Highlights](#-highlights)
9+
- [Add search functionality for pin names](#add-search-functionality-for-pin-names)
910
- [📝 Changelog](#-changelog)
1011
- [👨‍👩‍👧‍👦 Contributors](#-contributors)
1112

1213
### Overview
1314

1415
### 🔦 Highlights
1516

17+
#### Add search functionality for pin names
18+
19+
It is now possible to search for pins by name. To do so, use `ipfs pin ls --name "SomeName"`. The search is case-sensitive and will return all pins having a name which contains the exact word provided.
20+
1621
### 📝 Changelog
1722

1823
### 👨‍👩‍👧‍👦 Contributors

test/cli/pins_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,41 @@ func TestPins(t *testing.T) {
242242
require.NotContains(t, lsOut, outADetailed)
243243
})
244244

245+
t.Run("test listing pins which contains specific name", func(t *testing.T) {
246+
t.Parallel()
247+
248+
node := harness.NewT(t).NewNode().Init()
249+
cidAStr := node.IPFSAddStr(RandomStr(1000), "--pin=false")
250+
cidBStr := node.IPFSAddStr(RandomStr(1000), "--pin=false")
251+
cidCStr := node.IPFSAddStr(RandomStr(1000), "--pin=false")
252+
253+
outA := cidAStr + " recursive testPin"
254+
outB := cidBStr + " recursive testPin"
255+
outC := cidCStr + " recursive randPin"
256+
257+
_ = node.IPFS("pin", "add", "--name", "testPin", cidAStr)
258+
lsOut := pinLs(node, "-t=recursive", "--name=test")
259+
require.Contains(t, lsOut, outA)
260+
lsOut = pinLs(node, "-t=recursive", "--name=randomLabel")
261+
require.NotContains(t, lsOut, outA)
262+
263+
_ = node.IPFS("pin", "add", "--name", "testPin", cidBStr)
264+
lsOut = pinLs(node, "-t=recursive", "--name=test")
265+
require.Contains(t, lsOut, outA)
266+
require.Contains(t, lsOut, outB)
267+
268+
_ = node.IPFS("pin", "add", "--name", "randPin", cidCStr)
269+
lsOut = pinLs(node, "-t=recursive", "--name=rand")
270+
require.NotContains(t, lsOut, outA)
271+
require.NotContains(t, lsOut, outB)
272+
require.Contains(t, lsOut, outC)
273+
274+
lsOut = pinLs(node, "-t=recursive", "--name=testPin")
275+
require.Contains(t, lsOut, outA)
276+
require.Contains(t, lsOut, outB)
277+
require.NotContains(t, lsOut, outC)
278+
})
279+
245280
t.Run("test overwriting pin with name", func(t *testing.T) {
246281
t.Parallel()
247282

0 commit comments

Comments
 (0)