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

add --name new flag when ipfs adding from stdin #5399

Merged
merged 9 commits into from
Sep 13, 2018
Merged

Conversation

kjzz
Copy link
Contributor

@kjzz kjzz commented Aug 23, 2018

Closes #4986.

License: MIT
Signed-off-by: Kejie Zhang [email protected]

@@ -470,6 +472,9 @@ func (adder *Adder) addFile(file files.File) error {
return err
}

if !strings.EqualFold(adder.WpName, "") && adder.Wrap {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is the place a normal file is added, not the directory wrapper.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sorry for delay.you can look at this picture.
image
when i use command 'cat' to get file,you can use --name to name the file.Just like next picture.
image

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 have rebase repo and please help me review this pr @schomatis

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thank you!

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's drop the adder.Wrap check.

License: MIT
Signed-off-by: Kejie Zhang <[email protected]>
@schomatis
Copy link
Contributor

Hey @kjzz, take a look at #4986 (comment). We're mixing the name of the directory wrapper with the name of a file coming from stdin, which are two different issues.

Copy link
Contributor

@schomatis schomatis left a comment

Choose a reason for hiding this comment

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

The main issue in this review iteration is decoupling the --name flag from the -w flag, although they are related from the user perspective, in the code these are two different issues, and removing the wrap references could make the PR easier to understand.

@@ -37,6 +37,7 @@ const (
progressOptionName = "progress"
trickleOptionName = "trickle"
wrapOptionName = "wrap-with-directory"
wrapPathName = "name"
Copy link
Contributor

Choose a reason for hiding this comment

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

So, as discussed in the issue, this is not exactly related to the -w (wrap) flag, is a more generic issue of assigning names to a unnamed file content (such as the one received from stdin). Let's change the name of this option to reflect that, e.g., wrapPathName -> pathName.

@@ -116,6 +117,7 @@ You can now check what blocks have been created by:
cmdkit.BoolOption(trickleOptionName, "t", "Use trickle-dag format for dag generation."),
cmdkit.BoolOption(onlyHashOptionName, "n", "Only chunk and hash - do not write to disk."),
cmdkit.BoolOption(wrapOptionName, "w", "Wrap files with a directory object."),
cmdkit.StringOption(wrapPathName, "Assign path name when use wrap-with-directory option"),
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar to the above comment, let's drop the wrap reference and say something like: "Assign a name to an unnamed file" (feel free to reword this).

@@ -83,6 +84,7 @@ type Adder struct {
RawLeaves bool
Silent bool
Wrap bool
WpName string
Copy link
Contributor

Choose a reason for hiding this comment

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

WpName -> Name

@@ -470,6 +472,9 @@ func (adder *Adder) addFile(file files.File) error {
return err
}

if !strings.EqualFold(adder.WpName, "") && adder.Wrap {
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's drop the adder.Wrap check.

@@ -470,6 +472,9 @@ func (adder *Adder) addFile(file files.File) error {
return err
}

if !strings.EqualFold(adder.WpName, "") && adder.Wrap {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need an EqualFold call to compare to an empty string? I don't think the case is a problem here.

@@ -470,6 +472,9 @@ func (adder *Adder) addFile(file files.File) error {
return err
}

if !strings.EqualFold(adder.WpName, "") && adder.Wrap {
return adder.addNode(dagnode, adder.WpName)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd rather avoid duplicating the function call, we can define a new variable here, e.g., addFileName := file.FileName(), and if that name is "" we set it to adder.Name. e.g.,

addFileName := file.FileName()
if addFileName == "" && adder.Name != "" {
  addFileName = adder.Name

  adder.Name = ""
  // Unset the `Name` option to avoid applying the same name to many unnamed files.
  // TODO: This could be turned into a FIFO queue to handle the scenario with more than one unnamed file.
}

adder.addNode(dagnode, addFileName)

We do two checks:

  1. Apply the --name option only to unnamed files (e.g., coming from stdin).
  2. Apply the --name option only once (since I fear that the HTTP commands library may be able to send many unnamed files), otherwise we would have many files with the same name in one directory.

License: MIT
Signed-off-by: Kejie Zhang <[email protected]>
@kjzz
Copy link
Contributor Author

kjzz commented Sep 3, 2018

@schomatis thank you very much for your advice.I have modify my pr.

@schomatis schomatis requested a review from keks September 3, 2018 13:58
@@ -470,8 +471,13 @@ func (adder *Adder) addFile(file files.File) error {
return err
}

addFileName := file.FileName()
if addFileName == "" && adder.Name != "" {
Copy link
Contributor

Choose a reason for hiding this comment

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

@keks WDYT about checking for an empty filename? I think this covers the stdin case in CLI, I'm not sure what effect this may have in the HTTP case, that's why we're resetting the adder.Name option to rename only one file (in the case HTTP may send many unnamed files).

Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like there are several occasions where we use an empty string as file name. I just looked into this and it looks like when using stdin, te FullName() should be os.Stdin.Name(), i.e. /dev/stdin. IMHO that would be a better check, and should also possible on the http server side.

Copy link
Contributor Author

@kjzz kjzz Sep 4, 2018

Choose a reason for hiding this comment

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

hello @keks ,i want to fix this bug.And i do not understand theFullname().can u explain more for me? my pr is aim to solve issue #5399 . I have explain to @schomatis why I do for this.You can see at this . Thx.

Copy link
Contributor

Choose a reason for hiding this comment

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

@kjzz Sure! The file variable is a "files".File, an interface described here: https://godoc.org/github.com/ipfs/go-ipfs-cmdkit/files#File. It has the method FileName(), which is currently used in the check. But it also has the method FullName(), which should return /dev/stdin if the file is stdin. If you check file.FullName() == "/dev/stdin" or file.FullName() == os.Stdin.Name(), that should be more reliable, because there are other reasons why file.FileName() may be the empty string. I only grepped through the code in go-ipfs-cmds and saw a lot of files with empty string as name. I'm not sure this will be a problem in practice, but I can't rule out that it won't. I think checking file.FullName() should be much more reliable.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks @keks! That sounds much more robust, @kjzz, so the check would be

if file.FullName() == os.Stdin.Name() && adder.Name != "" {

Copy link
Contributor

@keks keks left a comment

Choose a reason for hiding this comment

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

Let's find a better way to check for stdin, looks good otherwise.

@@ -470,8 +471,13 @@ func (adder *Adder) addFile(file files.File) error {
return err
}

addFileName := file.FileName()
if addFileName == "" && adder.Name != "" {
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like there are several occasions where we use an empty string as file name. I just looked into this and it looks like when using stdin, te FullName() should be os.Stdin.Name(), i.e. /dev/stdin. IMHO that would be a better check, and should also possible on the http server side.

@@ -116,6 +117,7 @@ You can now check what blocks have been created by:
cmdkit.BoolOption(trickleOptionName, "t", "Use trickle-dag format for dag generation."),
cmdkit.BoolOption(onlyHashOptionName, "n", "Only chunk and hash - do not write to disk."),
cmdkit.BoolOption(wrapOptionName, "w", "Wrap files with a directory object."),
cmdkit.StringOption(pathName, "Assign path name when use wrap-with-directory option"),
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's change this to reflect that the option (with the new check) works only for stdin, e.g., "Assign a name if the file source is stdin" (or something like that, feel free to reword it).

@kjzz kjzz force-pushed the zkj/feat branch 2 times, most recently from 5433eea to ea9087c Compare September 5, 2018 01:31
@kjzz
Copy link
Contributor Author

kjzz commented Sep 5, 2018

@schomatis @keks In godoc,the file has a function named fullpath not fullname.So i use fullpath to judge the name, And In my test,if i use command such as

$cat ./test1.txt | ./ipfs add -w --name "myfile.txt"
added Qmf3xdREx34pewgYZjyvHQsrZxuk1TLUFdzoF95dsXfv3k myfile.txt
added QmSLquBbWRXs3VjTCJBXYv4BHn7NFNZxh5iU3zGNp5aMcf

the file path is also is empty string,I have log the full path in ipfs the log is:

09:20:50.138 INFO   coreunix: The file path is : add.go:475

not os.Stdin(/dev/stdin).
So please help me review my pr.

@schomatis
Copy link
Contributor

the file has a function named fullpath not fullname

You're right, we copied it incorrectly, it's FullPath().

I have log the full path in ipfs the log is:

09:20:50.138 INFO coreunix: The file path is : add.go:475
not os.Stdin(/dev/stdin).

Could you double check that please? If I add the line

fmt.Printf("Fullpath: %s\n", file.FullPath())

I'm seeing

Fullpath: /dev/stdin

(not an empty string).

Feel free to include the log line (temporarily) in the PR, to check that you're printing the correct attribute.

@kjzz
Copy link
Contributor Author

kjzz commented Sep 5, 2018

@schomatis
image
I have take a picture for you.And my computer is mac os.Maybe the computer system will cause difference?

@kjzz
Copy link
Contributor Author

kjzz commented Sep 5, 2018

@schomatis And I have pushed my log line in pr

@kjzz
Copy link
Contributor Author

kjzz commented Sep 5, 2018

@schomatis please help check it,Thx.

@schomatis
Copy link
Contributor

And my computer is mac os.Maybe the computer system will cause difference?

Yes, that must be it, because with your patch I'm still seeing the /dev/stdin.

@keks Thoughts?

@kjzz
Copy link
Contributor Author

kjzz commented Sep 5, 2018

@schomatis @keks so can i use

if (file.FullPath() == "/dev/stdin"||file.FullPath() == "") && adder.Name != "" {

to make different system compatible.

@kjzz
Copy link
Contributor Author

kjzz commented Sep 5, 2018

And i have done some compatible processing.It is OK? @schomatis @keks

License: MIT
Signed-off-by: Kejie Zhang <[email protected]>
Copy link
Contributor

@schomatis schomatis left a comment

Choose a reason for hiding this comment

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

@kjzz Great! Thanks for taking the time and effort to get this properly fixed.

@schomatis schomatis added RFM and removed status/in-progress In progress labels Sep 8, 2018
@@ -470,8 +471,14 @@ func (adder *Adder) addFile(file files.File) error {
return err
}

addFileName := file.FileName()
addFileInfo := file.(files.FileInfo)
Copy link
Member

Choose a reason for hiding this comment

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

@keks are you sure this won't panic in some cases? We should probably use a checked type assertion (or comment on why this must be true).

@kjzz
Copy link
Contributor Author

kjzz commented Sep 11, 2018

Hi @Stebalien , i have add a checked type assertion in pr.Maybe it will be more robust.

@@ -116,6 +117,7 @@ You can now check what blocks have been created by:
cmdkit.BoolOption(trickleOptionName, "t", "Use trickle-dag format for dag generation."),
cmdkit.BoolOption(onlyHashOptionName, "n", "Only chunk and hash - do not write to disk."),
cmdkit.BoolOption(wrapOptionName, "w", "Wrap files with a directory object."),
cmdkit.StringOption(pathName, "Assign a name if the file source is stdin."),
Copy link
Member

Choose a reason for hiding this comment

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

Given that this'll only work for STDIN, I'd consider calling this --stdin-name. I believe the original issue was suggesting a more general --name flag (even for regular files) but I actually prefer how this patch currently works.

Copy link
Contributor

Choose a reason for hiding this comment

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

That seams a little two verbose to me. Also, in the future want to allow this to override an existing name and then we will be stuck with both a --name and --stdin-name option.

For now I recommend we keep it as is and instead return an error (or maybe just a warning) when the option won't have any effect.

Copy link
Member

Choose a reason for hiding this comment

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

Also, in the future want to allow this to override an existing name and then we will be stuck with both a --name and --stdin-name option.

Actually, my thought was that this should never be a general-purpose flag. I believe that was the original suggestion but, as was discovered when writing this patch, that's ambiguous with multiple inputs. We also don't want to change the semantics at some point in the future (IMO).

Copy link
Member

Choose a reason for hiding this comment

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

We could also have a "rename" feature but we'll have to carefully consider how we want to do it.

Note, by "multiple inputs" I mean:

> ipfs add -w --name "foo" file1 file2

We can only ever have one stdin so setting the name for stdin is unambiguous. We can easily add multiple files at the same time.

@Stebalien
Copy link
Member

@keks @schomatis are we sure this is the best way to fix this? This feels like something that should be fixed in go-ipfs-cmds itself (i.e., allow a --stdin-name flag and use this to pick the name for files added via stdin).

Note: As long as we can get agree on the name of the flag, we can merge this as-is. I'm just really not a fan of stringly typed stuff and, as-is, this fix is a quite hacky.

License: MIT
Signed-off-by: Kejie Zhang <[email protected]>
License: MIT
Signed-off-by: Kejie Zhang <[email protected]>
@kjzz
Copy link
Contributor Author

kjzz commented Sep 11, 2018

hey @Stebalien , i have update the stdin-name,and i know what you worried about.And i think that this way is a useful way to fix the problem but maybe is the not best one.

@kjzz
Copy link
Contributor Author

kjzz commented Sep 12, 2018

@Stebalien If you have any advice,you can ping me.Thx a lot for helping me review pr.

@keks
Copy link
Contributor

keks commented Sep 12, 2018

@Stebalien Hm, yes that should also work. Now that you mention it, that would be cleaner. Maybe let's first get cmds#112 done, though :)

But yeah, --stdin-name is also good.

@schomatis
Copy link
Contributor

@Stebalien Agreed that this is far from optimal, but I think the patch is cleanly encapsulated inside the Adder and it doesn't decrease code quality. We can use this as a first step towards the correct solution inside go-ipfs-cmds, also @kjzz has invested a significant amount of time and effort following our (sub-optimal :) advice so it would be nice to get this merged.

@Stebalien
Copy link
Member

@schomatis, @keks you're right. This is a strict improvement, even if there's a better way to do this, we might as well merge this and improve it later.

@Stebalien
Copy link
Member

Stebalien commented Sep 12, 2018

Want to make sure @kevina and I are on the same page and then we can merge this. UX changes like this are always tricky...

@kevina
Copy link
Contributor

kevina commented Sep 12, 2018

@Stebalien if the goal is for this to only every work from naming an otherwise unnamed file from stdin I think I am okay with --stdin-name a more functional --name could also be useful, but if we are abandoning the idea I think I am okay with this.

I will get back to this later today or tomorrow and give my final approval then.

@kjzz
Copy link
Contributor Author

kjzz commented Sep 13, 2018

Hey @kevina , the pr is aimed at solving name an otherwise unnamed file from stdin,and i know it is not the best solution.And i will continue to perfect it in the next step.In addition,if @Stebalien have any new issue or advice about this,please ping me and i am very glad to work on it.Thx a lot.

@Stebalien
Copy link
Member

(this has 3 signoffs so I think it's ready to go; we can always change our minds later as long as we do it fast enough)

@Stebalien Stebalien merged commit 7213328 into ipfs:master Sep 13, 2018
@kevina
Copy link
Contributor

kevina commented Sep 14, 2018

Yeah I don't have a major problem with it --stdin-name.

@djdv
Copy link
Contributor

djdv commented Sep 19, 2018

I'm late on this, and not sure how important it is. But doesn't this unnecessarily break struct alignment?
https://github.com/kjzz/go-ipfs/blob/b7ea4bfc2a2c3b864d688c108245a3429029e185/core/coreunix/add.go#L79-L88

@keks
Copy link
Contributor

keks commented Sep 19, 2018

I guess it's not too bad because most bools are consecutive and form a 7-byte block of 1-byte aligned values. I guess we could swap Chunker and NoCopy to save eight bytes, or reorder the whole thing to have the bools at the bottom, but I'm not sure it's worth it.

@Stebalien
Copy link
Member

Yeah, we could fix this but this isn't exactly a bottleneck. Feel free to submit a patch if you want but it's probably not worth the time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RFM topic/commands Topic commands
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants