Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide new "cid" sub-command. #5385

Merged
merged 10 commits into from
Oct 2, 2018
Merged

Provide new "cid" sub-command. #5385

merged 10 commits into from
Oct 2, 2018

Conversation

kevina
Copy link
Contributor

@kevina kevina commented Aug 15, 2018

Implements #5357.

Still needs tests.

Closes #5229. Closes #5357.

@kevina kevina added the topic/cidv1b32 Topic cidv1b32 label Aug 15, 2018
@kevina kevina requested a review from Kubuxu as a code owner August 15, 2018 23:15
@ghost ghost assigned kevina Aug 15, 2018
@ghost ghost added the status/in-progress In progress label Aug 15, 2018
@kevina kevina force-pushed the kevina/cid-cmd branch 4 times, most recently from 1dc7a95 to b46e3d2 Compare August 22, 2018 01:49
` + cidutil.FormatRef,
},
Arguments: []cmdkit.Argument{
cmdkit.StringArg("cid", true, true, "Cids to format."),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use WithDefault("%s")?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You meant for the -f option? If it is omitted that is the default (see below), I just didn't use WithDefault. The idea was the -f is optional and if its not specified it will just return the CIDs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's nice from a documentation standpoint.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No Problem.

case "":
opts.fmtStr = "%s"
case "prefix":
opts.fmtStr = "%P"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels a bit magical. What's the motivation? We could also just add a ipfs cid prefix command (alias of ipfs cid format -f '%P' ...).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was there in the original cid-fmt utility and copied over here. For the cid-fmt utility is was the original use case (to get information about cids). I am not tied to keeping it in this utility.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd remove it for now. We can consider either a prefix or a show command later but we probably don't need them now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do.

opts.newBase = mbase.Encoding(-1)
}

res, err := formatCids(req.Arguments, opts)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd stream these results back. Users may want to feed quite a few CIDs into this command.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about that but didn't see the benefit. This is a client side utility that will never block and is should be very fast, so the only benefit will be memory usage. In addition the number of cid's passed in is limited by the length of command line so memory usage will never get out of control.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. Well, actually, arguments can be passed in on stdin (newline separated)... That's why I brought this up. Basically, a user may run something like ipfs refs -u -r QmThing | ipfs cid format -f '%c' | sort -u.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you have to do something special to make that work. Because when I tried it I get Error: argument "cid" is required. I actually think this it is a bit of a misfeature to take the arguments from stdin without having to pass in a special flag, but that something to debate later.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fwiw, I agree it's a misfeature to take arguments from stdin without a flag -- I think it's pretty widespread convention now to use a single dash "-" argument to mean "read stdin instead of file". (And that would make just as much sense for "read stdin instead of literal".)

@Stebalien
Copy link
Member

@alanshaw this adds a new ipfs cid command. I'm fine with keeping this command "go specific" (it's really just a utility command) but thought you might have some input.

Basically, it makes it easy to inspect CIDs and convert between various formats (bases, versions, etc.).

emit(str, err)
}
}()
resp.Emit(out)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just call Emit on each CID individually (no need for the goroutine or the channel).

@Stebalien
Copy link
Member

EnableStdin isn't broken, it's just that:

  1. The documentation is all missing.
  2. The API sucks.

Basically, you'll have to:

  1. Iterate over all the arguments in Arguments.
  2. Iterate over the arguments from BodyArgs().

You can also just call ParseBodyArgs() to move all the arguments from the body into Arguments.

@kevina
Copy link
Contributor Author

kevina commented Aug 27, 2018

You can also just call ParseBodyArgs() to move all the arguments from the body into Arguments.

That will prevent streaming.

@Stebalien
Copy link
Member

That will prevent streaming.

It will. The important part here is allowing ourselves to stream at some point in the future without breaking the API.

@kevina
Copy link
Contributor Author

kevina commented Aug 30, 2018

It will. The important part here is allowing ourselves to stream at some point in the future without breaking the API.

Please see the new commits. You can now stream. Sorry I didn't follow up in the comments.

Copy link
Member

@Stebalien Stebalien left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way to simplify this? We're introducing multiple new abstractions.

cmds.Text: cmds.MakeEncoder(func(req *cmds.Request, w io.Writer, val0 interface{}) error {
prefixes, _ := req.Options["prefix"].(bool)
numeric, _ := req.Options["numeric"].(bool)
val := val0.([]CodeAndName)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, you'll need to check if the type is correct. See: ipfs/go-ipfs-cmds#65. Basically, we end up feeding errors to this function as well.

(search the code for examples on how to do this).


// streamRes is a helper function to stream results, that possibly
// contain with non-fatal, the helper function is allowed to panic on
// internal errors
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs some proof-reading :).

// streamRes is a helper function to stream results, that possibly
// contain with non-fatal, the helper function is allowed to panic on
// internal errors
func streamRes(procVal func(interface{}, io.Writer) nonFatalError) func(*cmds.Request, cmds.ResponseEmitter) cmds.ResponseEmitter {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we call this streamResults? We tend to a bit too curt.

core/commands/commands.go Show resolved Hide resolved
if !ok {
break
}
emit := func(fmtd string, err error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's lift this out of the loop (I don't trust go).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's in the loop as it is a closure. I do it that way to avoid having to pass is the cidStr variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just eliminated the need for the emit function.

if err != nil {
res.ErrorMsg = err.Error()
}
resp.Emit(res)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should handle this error (the client may have gone away).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what I should do. Should I log the error and then just return?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made at attempt at handling this, please check that it is correct.

@kevina
Copy link
Contributor Author

kevina commented Aug 30, 2018

Is there any way to simplify this? We're introducing multiple new abstractions.

Most (all) of the abstractions are lifted from the filestore ls code when I am doing nearly the same thing. Most of the completely comes from the fact that I believe fairly strongly that we should not abort on non-fatal errors, especially when streaming.

@kevina
Copy link
Contributor Author

kevina commented Aug 30, 2018

Is there any way to simplify this? We're introducing multiple new abstractions.

On second thought. I am not 100% sure what you mean. I thought you where talking about the handling of the cid fotmat command and streaming? Is there anything else you are referring to?

@alanshaw
Copy link
Member

Hey everyone! I've tried to replicate the functionalty here as closely as possible for the jsipfs cid command. I'd appreciate it if you're able to spare a few minutes to look over https://github.com/ipfs-shipyard/js-cid-tool (if not the code, the README will do) to check I've captured the intentions correctly.

thank you ❤️

alanshaw pushed a commit to ipfs/js-ipfs that referenced this pull request Sep 13, 2018
This PR adds a `jsipfs cid` command with tools for formatting, converting and discovering properties of CIDs.

All the docs are here: https://github.com/ipfs-shipyard/js-cid-tool
Will resolve this for JS: ipfs/kubo#5229
go-ipfs counterpart: ipfs/kubo#5385

License: MIT
Signed-off-by: Alan Shaw <alan.shaw@protocol.ai>
@kevina
Copy link
Contributor Author

kevina commented Sep 14, 2018

@alanshaw I looked over the README and I think the tool captures the intentions about the same. It was never really my intention for these commands to become standardized except for perhaps the base32 command.

Note that some minor details of the behavior of these commands may change over time.

@kevina
Copy link
Contributor Author

kevina commented Sep 14, 2018

@Stebalien if this is too complicated, I can separate out the part that implements proper streaming into a separate p.r. as I think that is where most of the complexity your seeing is coming from...

@alanshaw
Copy link
Member

Thanks @kevina

It was never really my intention for these commands to become standardized

Understood, I haven't added this to any interface-* repos. I'm happy for this to just be a command line tool. I think it's important that jsipfs users also have it which is why I created it. Plus it was pretty quick and easy to put together.

@kevina kevina force-pushed the kevina/cid-cmd branch 2 times, most recently from 2973fdb to e21f234 Compare September 20, 2018 07:23
@kevina
Copy link
Contributor Author

kevina commented Sep 20, 2018

@Stebalien I rebased this to fix the merge conflict and update to the new command libraries. It still seams that GitHub is broken when displaying the changes. Let me know if you made any progress with GitHub support or if you want me to try creating a new p.r.

@kevina kevina mentioned this pull request Sep 21, 2018
8 tasks
Stebalien
Stebalien previously approved these changes Sep 25, 2018
@Stebalien
Copy link
Member

LGTM but I'm pulling in @warpfork for a second signoff (especially on the API, we can always fix the code later).

Kubuxu
Kubuxu previously approved these changes Sep 26, 2018
Copy link
Member

@Kubuxu Kubuxu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGWM.

It would be really nice if we could differentiate between API and until tool but we can. So I guess this is API now.

@Stebalien
Copy link
Member

@kevina I was just waiting on some second signoff. Now that we have one, this should be good to go. Unfortunately, it'll need a rebase. I'd squash first as doing this commit-by-commit is painful (I tried, but there were significant changes to the commands lib).

@kevina
Copy link
Contributor Author

kevina commented Oct 1, 2018

@Stebalien I rebase later today.

License: MIT
Signed-off-by: Kevin Atkinson <k@kevina.org>
License: MIT
Signed-off-by: Kevin Atkinson <k@kevina.org>
License: MIT
Signed-off-by: Kevin Atkinson <k@kevina.org>
Note reading input from Stdin is broken.  Only the first result is accepted.

License: MIT
Signed-off-by: Kevin Atkinson <k@kevina.org>
This also avoid using TabWriter as it doesn't support right aligning a
single column and also because its an overkill for this case.

License: MIT
Signed-off-by: Kevin Atkinson <k@kevina.org>
License: MIT
Signed-off-by: Kevin Atkinson <k@kevina.org>
License: MIT
Signed-off-by: Kevin Atkinson <k@kevina.org>
License: MIT
Signed-off-by: Kevin Atkinson <k@kevina.org>
License: MIT
Signed-off-by: Kevin Atkinson <k@kevina.org>
License: MIT
Signed-off-by: Kevin Atkinson <k@kevina.org>
@kevina
Copy link
Contributor Author

kevina commented Oct 1, 2018

@Stebalien actually I already rebased and fixed my code to use the new commands library as indicated in an earlier comment. I just rebased again and fixed a dep/import problem.

This should be good to go. There is one failed test in Jenkins, but I don't think that is related.

@kevina
Copy link
Contributor Author

kevina commented Oct 1, 2018

And it looks like rebasing caused GitHub to dismiss the earlier approving reviews...

@kevina
Copy link
Contributor Author

kevina commented Oct 1, 2018

@Stebalien Jenkins is now green.

@Stebalien
Copy link
Member

And it looks like rebasing caused GitHub to dismiss the earlier approving reviews...

Yeah, I just turned that off. Sorry.

@Stebalien Stebalien merged commit 021fc9f into master Oct 2, 2018
@Stebalien Stebalien deleted the kevina/cid-cmd branch October 2, 2018 22:55
@ghost ghost removed the status/in-progress In progress label Oct 2, 2018
alanshaw pushed a commit to ipfs/js-ipfs that referenced this pull request Oct 16, 2018
This PR adds a `jsipfs cid` command with tools for formatting, converting and discovering properties of CIDs.

All the docs are here: https://github.com/ipfs-shipyard/js-cid-tool
Will resolve this for JS: ipfs/kubo#5229
go-ipfs counterpart: ipfs/kubo#5385

License: MIT
Signed-off-by: Alan Shaw <alan.shaw@protocol.ai>
alanshaw pushed a commit to ipfs/js-ipfs that referenced this pull request Oct 17, 2018
This PR adds a `jsipfs cid` command with tools for formatting, converting and discovering properties of CIDs.

All the docs are here: https://github.com/ipfs-shipyard/js-cid-tool
Will resolve this for JS: ipfs/kubo#5229
go-ipfs counterpart: ipfs/kubo#5385

License: MIT
Signed-off-by: Alan Shaw <alan.shaw@protocol.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic/cidv1b32 Topic cidv1b32
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants