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: Fix adding multiple files #6255

Merged
merged 3 commits into from
Apr 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 52 additions & 46 deletions core/commands/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,24 +181,12 @@ You can now check what blocks have been created by:
return err
}

events := make(chan interface{}, adderOutChanSize)

var toadd files.Node = req.Files
name := ""
if !wrap {
it := req.Files.Entries()
if !it.Next() {
err := it.Err()
if err == nil {
return fmt.Errorf("expected a file argument")
}
return err
}

toadd = it.Node()
name = it.Name()
toadd := req.Files
if wrap {
toadd = files.NewSliceDirectory([]files.DirEntry{
files.FileEntry("", req.Files),
})
}
_, dir := toadd.(files.Directory)

opts := []options.UnixfsAddOption{
options.Unixfs.Hash(hashFunCode),
Expand All @@ -215,7 +203,6 @@ You can now check what blocks have been created by:

options.Unixfs.Progress(progress),
options.Unixfs.Silent(silent),
options.Unixfs.Events(events),
}

if cidVerSet {
Expand All @@ -230,42 +217,61 @@ You can now check what blocks have been created by:
opts = append(opts, options.Unixfs.Layout(options.TrickleLayout))
}

errCh := make(chan error, 1)
go func() {
var err error
defer func() { errCh <- err }()
defer close(events)
_, err = api.Unixfs().Add(req.Context, toadd, opts...)
}()

for event := range events {
output, ok := event.(*coreiface.AddEvent)
if !ok {
return errors.New("unknown event type")
}
opts = append(opts, nil) // events option placeholder

h := ""
if output.Path != nil {
h = enc.Encode(output.Path.Cid())
}
var added int
addit := toadd.Entries()
for addit.Next() {
_, dir := addit.Node().(files.Directory)
errCh := make(chan error, 1)
events := make(chan interface{}, adderOutChanSize)
opts[len(opts)-1] = options.Unixfs.Events(events)
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we shouldn't be closing this channel?

Copy link
Member

Choose a reason for hiding this comment

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

Otherwise, we could drop the need for the nil option by writing:

opts := append(opts, options.Unixfs.Events(events)) // note the :=


go func() {
var err error
defer close(events)
_, err = api.Unixfs().Add(req.Context, addit.Node(), opts...)
errCh <- err
}()

for event := range events {
output, ok := event.(*coreiface.AddEvent)
if !ok {
return errors.New("unknown event type")
}

h := ""
if output.Path != nil {
h = enc.Encode(output.Path.Cid())
}

if !dir && addit.Name() != "" {
output.Name = addit.Name()
} else {
output.Name = path.Join(addit.Name(), output.Name)
}

if !dir && name != "" {
output.Name = name
} else {
output.Name = path.Join(name, output.Name)
if err := res.Emit(&AddEvent{
Name: output.Name,
Hash: h,
Bytes: output.Bytes,
Size: output.Size,
}); err != nil {
return err
}
}

if err := res.Emit(&AddEvent{
Name: output.Name,
Hash: h,
Bytes: output.Bytes,
Size: output.Size,
}); err != nil {
if err := <-errCh; err != nil {
return err
}
added++
}

return <-errCh
if added == 0 {
return fmt.Errorf("expected a file argument")
}

return nil
},
PostRun: cmds.PostRunMap{
cmds.CLI: func(res cmds.Response, re cmds.ResponseEmitter) error {
Expand Down
10 changes: 10 additions & 0 deletions test/sharness/t0040-add-and-cat.sh
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,16 @@ test_add_cat_file() {
test_cmp expected actual
'

test_expect_success "ipfs add with multiple files succeeds" '
echo "Helloo Worlds!" >mountdir/hello2.txt &&
ipfs add mountdir/hello.txt mountdir/hello2.txt >actual
'

test_expect_success "ipfs add with multiple files output looks good" '
echo "added QmVr26fY1tKyspEJBniVhqxQeEjhF78XerGiqWAwraVLQH hello.txt" >expected &&
echo "added Qmf35k66MZNW2GijohUmXQEWKZU4cCGTCwK6idfnt152wJ hello2.txt" >> expected &&
test_cmp expected actual
'
}

test_add_cat_5MB() {
Expand Down