Skip to content

Commit

Permalink
feat: add --detailed option to ipfs pin ls
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed Jan 3, 2024
1 parent f98d02c commit 9a5e790
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 27 deletions.
17 changes: 10 additions & 7 deletions core/commands/pin/pin.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,9 +280,10 @@ ipfs pin ls -t indirect <cid>
}

const (
pinTypeOptionName = "type"
pinQuietOptionName = "quiet"
pinStreamOptionName = "stream"
pinTypeOptionName = "type"
pinQuietOptionName = "quiet"
pinStreamOptionName = "stream"
pinDetailedOptionName = "detailed"
)

var listPinCmd = &cmds.Command{
Expand Down Expand Up @@ -336,6 +337,7 @@ Example:
cmds.StringOption(pinTypeOptionName, "t", "The type of pinned keys to list. Can be \"direct\", \"indirect\", \"recursive\", or \"all\".").WithDefault("all"),
cmds.BoolOption(pinQuietOptionName, "q", "Write just hashes of objects."),
cmds.BoolOption(pinStreamOptionName, "s", "Enable streaming of pins as they are discovered."),
cmds.BoolOption(pinDetailedOptionName, "d", "Enable displaying additional information, such as pin names (slower)."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env, req)
Expand All @@ -345,6 +347,7 @@ Example:

typeStr, _ := req.Options[pinTypeOptionName].(string)
stream, _ := req.Options[pinStreamOptionName].(bool)
detailed, _ := req.Options[pinDetailedOptionName].(bool)

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

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

pins, err := api.Pin().Ls(req.Context, opt)
pins, err := api.Pin().Ls(req.Context, opt, options.Pin.Ls.Detailed(detailed))
if err != nil {
return err
}
Expand Down Expand Up @@ -757,7 +760,7 @@ func pinVerify(ctx context.Context, n *core.IpfsNode, opts pinVerifyOpts, enc ci
out := make(chan any)
go func() {
defer close(out)
for p := range n.Pinning.RecursiveKeys(ctx) {
for p := range n.Pinning.RecursiveKeys(ctx, false) {
if p.Err != nil {
out <- PinVerifyRes{Err: p.Err.Error()}
return
Expand Down
14 changes: 7 additions & 7 deletions core/coreapi/pin.go
Original file line number Diff line number Diff line change
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), nil
return api.pinLsAll(ctx, settings.Type, settings.Detailed), nil
}

func (api *PinAPI) IsPinned(ctx context.Context, p path.Path, opts ...caopts.PinIsPinnedOption) (string, bool, error) {
Expand Down Expand Up @@ -231,7 +231,7 @@ func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, erro
out := make(chan coreiface.PinStatus)
go func() {
defer close(out)
for p := range api.pinning.RecursiveKeys(ctx) {
for p := range api.pinning.RecursiveKeys(ctx, false) {
var res *pinStatus
if p.Err != nil {
res = &pinStatus{err: p.Err}
Expand Down Expand Up @@ -276,7 +276,7 @@ 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) <-chan coreiface.Pin {
func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string, detailed bool) <-chan coreiface.Pin {
out := make(chan coreiface.Pin, 1)

emittedSet := cid.NewSet()
Expand All @@ -302,7 +302,7 @@ func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreifac
var rkeys []cid.Cid
var err error
if typeStr == "recursive" || typeStr == "all" {
for streamedCid := range api.pinning.RecursiveKeys(ctx) {
for streamedCid := range api.pinning.RecursiveKeys(ctx, detailed) {
if streamedCid.Err != nil {
out <- &pinInfo{err: streamedCid.Err}
return
Expand All @@ -315,7 +315,7 @@ func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreifac
}
}
if typeStr == "direct" || typeStr == "all" {
for streamedCid := range api.pinning.DirectKeys(ctx) {
for streamedCid := range api.pinning.DirectKeys(ctx, detailed) {
if streamedCid.Err != nil {
out <- &pinInfo{err: streamedCid.Err}
return
Expand All @@ -330,15 +330,15 @@ func (api *PinAPI) pinLsAll(ctx context.Context, typeStr string) <-chan coreifac
// We need to first visit the direct pins that have priority
// without emitting them

for streamedCid := range api.pinning.DirectKeys(ctx) {
for streamedCid := range api.pinning.DirectKeys(ctx, detailed) {
if streamedCid.Err != nil {
out <- &pinInfo{err: streamedCid.Err}
return
}
emittedSet.Add(streamedCid.Pin.Key)
}

for streamedCid := range api.pinning.RecursiveKeys(ctx) {
for streamedCid := range api.pinning.RecursiveKeys(ctx, detailed) {
if streamedCid.Err != nil {
out <- &pinInfo{err: streamedCid.Err}
return
Expand Down
12 changes: 11 additions & 1 deletion core/coreiface/options/pin.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ type PinAddSettings struct {

// PinLsSettings represent the settings for PinAPI.Ls
type PinLsSettings struct {
Type string
Type string
Detailed bool
}

// PinIsPinnedSettings represent the settings for PinAPI.IsPinned
Expand Down Expand Up @@ -195,6 +196,15 @@ func (pinLsOpts) pinType(t string) PinLsOption {
}
}

// Detailed is an option for [Pin.Ls] which sets whether or not to return
// detailed information, such as pin names and modes.
func (pinLsOpts) Detailed(detailed bool) PinLsOption {
return func(settings *PinLsSettings) error {
settings.Detailed = detailed
return nil
}
}

type pinIsPinnedOpts struct{}

// All is an option for Pin.IsPinned which will make it search in all type of pins.
Expand Down
5 changes: 5 additions & 0 deletions docs/changelogs/v0.26.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- [Overview](#overview)
- [🔦 Highlights](#-highlights)
- [Several deprecated commands have been removed](#several-deprecated-commands-have-been-removed)
- [Support optional pin names](#support-optional-pin-names)
- [📝 Changelog](#-changelog)
- [👨‍👩‍👧‍👦 Contributors](#-contributors)

Expand All @@ -30,6 +31,10 @@ Several deprecated commands have been removed:
- `ipfs dns` deprecated in [April 2022, Kubo 0.13](https://github.com/ipfs/kubo/commit/76ae33a9f3f9abd166d1f6f23d6a8a0511510e3c), use `ipfs resolve /ipns/{name}` instead.
- `ipfs tar` deprecated [April 2022, Kubo 0.13](https://github.com/ipfs/kubo/pull/8849)

#### Support optional pin names

You can now add a name to a pin when pinning a CID. To do so, use `ipfs pin add --name "Some Name" bafy...`. You can list your pins, including their names, with `ipfs pin ls --detailed`.

### 📝 Changelog

- Export a `kubo.Start` function so users can programmatically start Kubo from within a go program.
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/kubo-as-a-library/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ go 1.20
replace github.com/ipfs/kubo => ./../../..

require (
github.com/ipfs/boxo v0.16.1-0.20240102112808-a73b1877dbf8
github.com/ipfs/boxo v0.16.1-0.20240102133734-dc2f8b06ce71
github.com/ipfs/kubo v0.0.0-00010101000000-000000000000
github.com/libp2p/go-libp2p v0.32.2
github.com/multiformats/go-multiaddr v0.12.0
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/kubo-as-a-library/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -303,8 +303,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy
github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI=
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
github.com/ipfs/boxo v0.16.1-0.20240102112808-a73b1877dbf8 h1:J7v8ilV3rJDSFuEIIfQfEwqYBrdoksTenVRdpUzrpiU=
github.com/ipfs/boxo v0.16.1-0.20240102112808-a73b1877dbf8/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0=
github.com/ipfs/boxo v0.16.1-0.20240102133734-dc2f8b06ce71 h1:4WeZGWkOD4Wr2aGm7xXWdwGgPZbCYHjaz+gVaxx1sJ8=
github.com/ipfs/boxo v0.16.1-0.20240102133734-dc2f8b06ce71/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0=
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY=
Expand Down
6 changes: 3 additions & 3 deletions gc/gc.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ func ColoredSet(ctx context.Context, pn pin.Pinner, ng ipld.NodeGetter, bestEffo
}
return links, nil
}
rkeys := pn.RecursiveKeys(ctx)
rkeys := pn.RecursiveKeys(ctx, false)
err := Descendants(ctx, getLinks, gcs, rkeys)
if err != nil {
errors = true
Expand Down Expand Up @@ -270,15 +270,15 @@ func ColoredSet(ctx context.Context, pn pin.Pinner, ng ipld.NodeGetter, bestEffo
}
}

dkeys := pn.DirectKeys(ctx)
dkeys := pn.DirectKeys(ctx, false)
for k := range dkeys {
if k.Err != nil {
return nil, k.Err
}
gcs.Add(toCidV1(k.Pin.Key))
}

ikeys := pn.InternalPins(ctx)
ikeys := pn.InternalPins(ctx, false)
err = Descendants(ctx, getLinks, gcs, ikeys)
if err != nil {
errors = true
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require (
github.com/hashicorp/go-multierror v1.1.1
github.com/ipfs-shipyard/nopfs v0.0.12-0.20231027223058-cde3b5ba964c
github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c
github.com/ipfs/boxo v0.16.1-0.20240102112808-a73b1877dbf8
github.com/ipfs/boxo v0.16.1-0.20240102133734-dc2f8b06ce71
github.com/ipfs/go-block-format v0.2.0
github.com/ipfs/go-cid v0.4.1
github.com/ipfs/go-cidutil v0.1.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy
github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI=
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
github.com/ipfs/boxo v0.16.1-0.20240102112808-a73b1877dbf8 h1:J7v8ilV3rJDSFuEIIfQfEwqYBrdoksTenVRdpUzrpiU=
github.com/ipfs/boxo v0.16.1-0.20240102112808-a73b1877dbf8/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0=
github.com/ipfs/boxo v0.16.1-0.20240102133734-dc2f8b06ce71 h1:4WeZGWkOD4Wr2aGm7xXWdwGgPZbCYHjaz+gVaxx1sJ8=
github.com/ipfs/boxo v0.16.1-0.20240102133734-dc2f8b06ce71/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0=
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ=
Expand Down
33 changes: 33 additions & 0 deletions test/cli/pins_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/ipfs/go-cid"
"github.com/ipfs/kubo/test/cli/harness"
"github.com/ipfs/kubo/test/cli/testutils"
. "github.com/ipfs/kubo/test/cli/testutils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -209,4 +210,36 @@ func TestPins(t *testing.T) {
testPins(t, testPinsArgs{runDaemon: true, baseArg: "--cid-base=base32"})
testPins(t, testPinsArgs{runDaemon: true, lsArg: "--stream", baseArg: "--cid-base=base32"})
})

t.Run("test pinning with names", func(t *testing.T) {
t.Parallel()

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

_ = node.IPFS("pin", "add", "--name", "testPin", cidAStr)

outARegular := cidAStr + " recursive"
outADetailed := outARegular + " testPin"
outBRegular := cidBStr + " recursive"
outBDetailed := outBRegular + " testPin"

pinLs := func(args ...string) []string {
return strings.Split(node.IPFS(StrCat("pin", "ls", args)...).Stdout.Trimmed(), "\n")
}

lsOut := pinLs("-t=recursive")
require.Contains(t, lsOut, outARegular)
require.NotContains(t, lsOut, outADetailed)

lsOut = pinLs("-t=recursive", "--detailed")
require.Contains(t, lsOut, outADetailed)
require.NotContains(t, lsOut, outARegular)

_ = node.IPFS("pin", "update", cidAStr, cidBStr)
lsOut = pinLs("-t=recursive", "--detailed")
require.Contains(t, lsOut, outBDetailed)
require.NotContains(t, lsOut, outADetailed)
})
}
2 changes: 1 addition & 1 deletion test/dependencies/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ require (
github.com/hexops/gotextdiff v1.0.3 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/ipfs/bbloom v0.0.4 // indirect
github.com/ipfs/boxo v0.16.1-0.20240102112808-a73b1877dbf8 // indirect
github.com/ipfs/boxo v0.16.1-0.20240102133734-dc2f8b06ce71 // indirect
github.com/ipfs/go-block-format v0.2.0 // indirect
github.com/ipfs/go-cid v0.4.1 // indirect
github.com/ipfs/go-datastore v0.6.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions test/dependencies/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
github.com/ipfs/boxo v0.16.1-0.20240102112808-a73b1877dbf8 h1:J7v8ilV3rJDSFuEIIfQfEwqYBrdoksTenVRdpUzrpiU=
github.com/ipfs/boxo v0.16.1-0.20240102112808-a73b1877dbf8/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0=
github.com/ipfs/boxo v0.16.1-0.20240102133734-dc2f8b06ce71 h1:4WeZGWkOD4Wr2aGm7xXWdwGgPZbCYHjaz+gVaxx1sJ8=
github.com/ipfs/boxo v0.16.1-0.20240102133734-dc2f8b06ce71/go.mod h1:jAgpNQn7T7BnibUeReXcKU9Ha1xmYNyOlwVEl193ow0=
github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs=
github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM=
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
Expand Down

0 comments on commit 9a5e790

Please sign in to comment.