Skip to content

Commit

Permalink
feat: enables searching pins by name
Browse files Browse the repository at this point in the history
  • Loading branch information
gystemd committed May 8, 2024
1 parent 2841ec0 commit 98710de
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 8 deletions.
8 changes: 5 additions & 3 deletions core/commands/pin/pin.go
Expand Up @@ -362,6 +362,7 @@ Example:
cmds.BoolOption(pinQuietOptionName, "q", "Write just hashes of objects."),
cmds.BoolOption(pinStreamOptionName, "s", "Enable streaming of pins as they are discovered."),
cmds.BoolOption(pinNamesOptionName, "n", "Enable displaying pin names (slower)."),
cmds.StringOption(pinNameOptionName, "Display only pins with the given name."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env, req)
Expand All @@ -372,6 +373,7 @@ Example:
typeStr, _ := req.Options[pinTypeOptionName].(string)
stream, _ := req.Options[pinStreamOptionName].(bool)
displayNames, _ := req.Options[pinNamesOptionName].(bool)
name, _ := req.Options[pinNameOptionName].(string)

switch typeStr {
case "all", "direct", "indirect", "recursive":
Expand All @@ -397,7 +399,7 @@ Example:
if len(req.Arguments) > 0 {
err = pinLsKeys(req, typeStr, api, emit)
} else {
err = pinLsAll(req, typeStr, displayNames, api, emit)
err = pinLsAll(req, typeStr, displayNames || name != "", name, api, emit)
}
if err != nil {
return err
Expand Down Expand Up @@ -537,7 +539,7 @@ func pinLsKeys(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fu
return nil
}

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

pins, err := api.Pin().Ls(req.Context, opt, options.Pin.Ls.Detailed(detailed))
pins, err := api.Pin().Ls(req.Context, opt, options.Pin.Ls.Detailed(detailed), options.Pin.Ls.Name(name))
if err != nil {
return err
}
Expand Down
10 changes: 5 additions & 5 deletions core/coreapi/pin.go
Expand Up @@ -67,7 +67,7 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) (<-chan c
return nil, fmt.Errorf("invalid type '%s', must be one of {direct, indirect, recursive, all}", settings.Type)
}

return api.pinLsAll(ctx, settings.Type, settings.Detailed), nil
return api.pinLsAll(ctx, settings.Type, settings.Detailed, settings.Name), nil
}

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

emittedSet := cid.NewSet()

AddToResultKeys := func(c cid.Cid, name, typeStr string) error {
if emittedSet.Visit(c) {
AddToResultKeys := func(c cid.Cid, pinName, typeStr string) error {
if emittedSet.Visit(c) && (name == "" || name == pinName) {
select {
case out <- &pinInfo{
pinType: typeStr,
name: name,
name: pinName,
path: path.FromCid(c),
}:
case <-ctx.Done():
Expand Down
8 changes: 8 additions & 0 deletions core/coreiface/options/pin.go
Expand Up @@ -12,6 +12,7 @@ type PinAddSettings struct {
type PinLsSettings struct {
Type string
Detailed bool
Name string
}

// PinIsPinnedSettings represent the settings for PinAPI.IsPinned
Expand Down Expand Up @@ -205,6 +206,13 @@ func (pinLsOpts) Detailed(detailed bool) PinLsOption {
}
}

func (pinLsOpts) Name(name string) PinLsOption {
return func(settings *PinLsSettings) error {
settings.Name = name
return nil
}
}

type pinIsPinnedOpts struct{}

// All is an option for Pin.IsPinned which will make it search in all type of pins.
Expand Down
4 changes: 4 additions & 0 deletions docs/changelogs/v0.29.md
Expand Up @@ -6,13 +6,17 @@

- [Overview](#overview)
- [πŸ”¦ Highlights](#-highlights)
- [Add search functionality for pin names](#add-search-functionality-for-pin-names)
- [πŸ“ Changelog](#-changelog)
- [πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors](#-contributors)

### Overview

### πŸ”¦ Highlights

#### Add search functionality for pin names
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 with the exact name provided.

### πŸ“ Changelog

### πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors
37 changes: 37 additions & 0 deletions test/cli/pins_test.go
Expand Up @@ -242,6 +242,43 @@ func TestPins(t *testing.T) {
require.NotContains(t, lsOut, outADetailed)
})

t.Run("test listing pins with specific name", func(t *testing.T) {
print("test pinning with names cli text output")
t.Parallel()

node := harness.NewT(t).NewNode().Init()
cidAStr := node.IPFSAddStr(RandomStr(1000), "--pin=false")
cidBStr := node.IPFSAddStr(RandomStr(1000), "--pin=false")
cidCStr := node.IPFSAddStr(RandomStr(1000), "--pin=false")

outA := cidAStr + " recursive testPin"
outB := cidBStr + " recursive testPin"
outC := cidCStr + " recursive randPin"

_ = node.IPFS("pin", "add", "--name", "testPin", cidAStr)
lsOut := pinLs(node, "-t=recursive", "--name=testPin")
require.Contains(t, lsOut, outA)
lsOut = pinLs(node, "-t=recursive", "--name=randomLabel")
require.NotContains(t, lsOut, outA)

_ = node.IPFS("pin", "add", "--name", "testPin", cidBStr)
lsOut = pinLs(node, "-t=recursive", "--name=testPin")
require.Contains(t, lsOut, outA)
require.Contains(t, lsOut, outB)

_ = node.IPFS("pin", "add", "--name", "randPin", cidCStr)
lsOut = pinLs(node, "-t=recursive", "--name=randPin")
require.NotContains(t, lsOut, outA)
require.NotContains(t, lsOut, outB)
require.Contains(t, lsOut, outC)

lsOut = pinLs(node, "-t=recursive", "--name=testPin")
require.Contains(t, lsOut, outA)
require.Contains(t, lsOut, outB)
require.NotContains(t, lsOut, outC)

})

t.Run("test overwriting pin with name", func(t *testing.T) {
t.Parallel()

Expand Down

0 comments on commit 98710de

Please sign in to comment.