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: Allow proper adding of multiple directories with a single add call #3300

Closed
wants to merge 1 commit into from
Closed
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
2 changes: 1 addition & 1 deletion commands/cli/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ func appendFile(fpath string, argDef *cmds.Argument, recursive, hidden bool) (fi
}
}

return files.NewSerialFile(path.Base(fpath), fpath, hidden, stat)
return files.NewSerialFile(path.Base(fpath), fpath, hidden, true, stat)
}

// Inform the user if a file is waiting on input
Expand Down
4 changes: 4 additions & 0 deletions commands/files/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ type File interface {
// (and therefor supports calling `Read` and `Close`)
IsDirectory() bool

// IsRoot returns whether or not this file (or directory) is the 'root' of
// a given operation.
IsRoot() bool

// NextFile returns the next child file available (if the File is a
// directory). It will return (nil, io.EOF) if no more files are
// available. If the file is a regular file (not a directory), NextFile
Expand Down
7 changes: 6 additions & 1 deletion commands/files/linkfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ type Symlink struct {
path string
Target string
stat os.FileInfo
root bool

reader io.Reader
}

func NewLinkFile(name, path, target string, stat os.FileInfo) File {
func NewLinkFile(name, path, target string, stat os.FileInfo) *Symlink {
return &Symlink{
name: name,
path: path,
Expand Down Expand Up @@ -48,3 +49,7 @@ func (f *Symlink) FullPath() string {
func (f *Symlink) Read(b []byte) (int, error) {
return f.reader.Read(b)
}

func (f *Symlink) IsRoot() bool {
return f.root
}
5 changes: 5 additions & 0 deletions commands/files/multipartfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type MultipartFile struct {
Part *multipart.Part
Reader *multipart.Reader
Mediatype string
Root bool
}

func NewFileFromPart(part *multipart.Part) (File, error) {
Expand Down Expand Up @@ -105,3 +106,7 @@ func (f *MultipartFile) Close() error {
}
return f.Part.Close()
}

func (f *MultipartFile) IsRoot() bool {
return f.Root
}
12 changes: 11 additions & 1 deletion commands/files/readerfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@ type ReaderFile struct {
fullpath string
reader io.ReadCloser
stat os.FileInfo
root bool
}

func NewReaderFile(filename, path string, reader io.ReadCloser, stat os.FileInfo) *ReaderFile {
return &ReaderFile{filename, path, reader, stat}
return &ReaderFile{
filename: filename,
fullpath: path,
reader: reader,
stat: stat,
}
}

func (f *ReaderFile) IsDirectory() bool {
Expand Down Expand Up @@ -53,3 +59,7 @@ func (f *ReaderFile) Size() (int64, error) {
}
return f.stat.Size(), nil
}

func (f *ReaderFile) IsRoot() bool {
return f.root
}
23 changes: 18 additions & 5 deletions commands/files/serialfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,39 @@ type serialFile struct {
stat os.FileInfo
current *File
handleHiddenFiles bool
root bool
}

func NewSerialFile(name, path string, hidden bool, stat os.FileInfo) (File, error) {
func NewSerialFile(name, path string, hidden, root bool, stat os.FileInfo) (File, error) {
if root {
name = path
}
switch mode := stat.Mode(); {
case mode.IsRegular():
file, err := os.Open(path)
if err != nil {
return nil, err
}
return NewReaderFile(name, path, file, stat), nil
rf := NewReaderFile(name, path, file, stat)
rf.root = root
return rf, nil
case mode.IsDir():
// for directories, stat all of the contents first, so we know what files to
// open when NextFile() is called
contents, err := ioutil.ReadDir(path)
if err != nil {
return nil, err
}
return &serialFile{name, path, contents, stat, nil, hidden}, nil
return &serialFile{name, path, contents, stat, nil, hidden, root}, nil
case mode&os.ModeSymlink != 0:
target, err := os.Readlink(path)
if err != nil {
return nil, err
}
return NewLinkFile(name, path, target, stat), nil

lf := NewLinkFile(name, path, target, stat)
lf.root = root
return lf, nil
default:
return nil, fmt.Errorf("Unrecognized file type for %s: %s", name, mode.String())
}
Expand All @@ -55,6 +64,10 @@ func (f *serialFile) IsDirectory() bool {
return true
}

func (f *serialFile) IsRoot() bool {
return f.root
}

func (f *serialFile) NextFile() (File, error) {
// if a file was opened previously, close it
err := f.Close()
Expand Down Expand Up @@ -86,7 +99,7 @@ func (f *serialFile) NextFile() (File, error) {
// recursively call the constructor on the next file
// if it's a regular file, we will open it as a ReaderFile
// if it's a directory, files in it will be opened serially
sf, err := NewSerialFile(fileName, filePath, f.handleHiddenFiles, stat)
sf, err := NewSerialFile(fileName, filePath, f.handleHiddenFiles, false, stat)
if err != nil {
return nil, err
}
Expand Down
11 changes: 10 additions & 1 deletion commands/files/slicefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@ type SliceFile struct {
path string
files []File
n int
root bool
}

func NewSliceFile(filename, path string, files []File) *SliceFile {
return &SliceFile{filename, path, files, 0}
return &SliceFile{
filename: filename,
path: path,
files: files,
}
}

func (f *SliceFile) IsDirectory() bool {
Expand Down Expand Up @@ -74,3 +79,7 @@ func (f *SliceFile) Size() (int64, error) {

return size, nil
}

func (f *SliceFile) IsRoot() bool {
return f.root
}
36 changes: 21 additions & 15 deletions core/coreunix/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,24 +187,30 @@ func (adder *Adder) Finalize() (*dag.Node, error) {
return nil, err
}

var name string
if !adder.Wrap {
name = rootNode.Links[0].Name

dir, ok := adder.mr.GetValue().(*mfs.Directory)
if !ok {
return nil, fmt.Errorf("root is not a directory")
}

root, err = dir.Child(name)
if adder.Wrap {
err = adder.outputDirs("", root)
if err != nil {
return nil, err
}
}
} else {
for _, lnk := range rootNode.Links {
name := lnk.Name

err = adder.outputDirs(name, root)
if err != nil {
return nil, err
dir, ok := adder.mr.GetValue().(*mfs.Directory)
if !ok {
return nil, fmt.Errorf("root is not a directory")
}

root, err = dir.Child(name)
if err != nil {
return nil, err
}

err = adder.outputDirs(name, root)
if err != nil {
return nil, err
}
}
}

err = adder.mr.Close()
Expand Down Expand Up @@ -272,7 +278,7 @@ func AddR(n *core.IpfsNode, root string) (key string, err error) {
return "", err
}

f, err := files.NewSerialFile(root, root, false, stat)
f, err := files.NewSerialFile(root, root, false, true, stat)
if err != nil {
return "", err
}
Expand Down
2 changes: 1 addition & 1 deletion importer/importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func BuildDagFromFile(fpath string, ds dag.DAGService) (*dag.Node, error) {
return nil, fmt.Errorf("`%s` is a directory", fpath)
}

f, err := files.NewSerialFile(fpath, fpath, false, stat)
f, err := files.NewSerialFile(fpath, fpath, false, true, stat)
if err != nil {
return nil, err
}
Expand Down
22 changes: 13 additions & 9 deletions test/sharness/t0040-add-and-cat.sh
Original file line number Diff line number Diff line change
Expand Up @@ -306,12 +306,14 @@ test_expect_success "'ipfs add -r' succeeds" '
'

test_expect_success "'ipfs add -r' output looks good" '
MOUNTDIR="QmcgF3bEc3q9G9YfxCXWYaV5H7bDyDD1CrsmUDgSQPdY4n" &&
PLANETS="QmWSgS32xQEcXMeqd3YPJLrNBLSdsfYCep2U7CFkyrjXwY" &&
MARS="QmPrrHqJzto9m7SyiRzarwkqPcCSsKR2EB1AyqJfe8L8tN" &&
VENUS="QmU5kp3BH3B8tnWUU2Pikdb2maksBNkb92FHRr56hyghh4" &&
echo "added $MARS planets/mars.txt" >expected &&
echo "added $VENUS planets/venus.txt" >>expected &&
echo "added $PLANETS planets" >>expected &&
echo "added $MARS mountdir/planets/mars.txt" >expected &&
echo "added $VENUS mountdir/planets/venus.txt" >>expected &&
echo "added $PLANETS mountdir/planets" >>expected &&
echo "added $MOUNTDIR mountdir" >>expected &&
test_cmp expected actual
'

Expand All @@ -325,18 +327,20 @@ test_expect_success "'ipfs add -rn' succeeds" '
'

test_expect_success "'ipfs add -rn' output looks good" '
MDMOONS="QmT8p74vZ2WUmN5bV6DThsEvVkiCESz5ZTT4xoFuF9r1My" &&
MOONS="QmVKvomp91nMih5j6hYBA8KjbiaYvEetU2Q7KvtZkLe9nQ" &&
EUROPA="Qmbjg7zWdqdMaK2BucPncJQDxiALExph5k3NkQv5RHpccu" &&
JUPITER="QmS5mZddhFPLWFX3w6FzAy9QxyYkaxvUpsWCtZ3r7jub9J" &&
SATURN="QmaMagZT4rTE7Nonw8KGSK4oe1bh533yhZrCo1HihSG8FK" &&
TITAN="QmZzppb9WHn552rmRqpPfgU5FEiHH6gDwi3MrB9cTdPwdb" &&
MERCURY="QmUJjVtnN8YEeYcS8VmUeWffTWhnMQAkk5DzZdKnPhqUdK" &&
echo "added $EUROPA moons/jupiter/europa.txt" >expected &&
echo "added $MERCURY moons/mercury.txt" >>expected &&
echo "added $TITAN moons/saturn/titan.txt" >>expected &&
echo "added $JUPITER moons/jupiter" >>expected &&
echo "added $SATURN moons/saturn" >>expected &&
echo "added $MOONS moons" >>expected &&
echo "added $EUROPA mountdir/moons/jupiter/europa.txt" >expected &&
echo "added $MERCURY mountdir/moons/mercury.txt" >>expected &&
echo "added $TITAN mountdir/moons/saturn/titan.txt" >>expected &&
echo "added $JUPITER mountdir/moons/jupiter" >>expected &&
echo "added $SATURN mountdir/moons/saturn" >>expected &&
echo "added $MOONS mountdir/moons" >>expected &&
echo "added $MDMOONS mountdir" >>expected &&
test_cmp expected actual
'

Expand Down
24 changes: 13 additions & 11 deletions test/sharness/t0042-add-skip.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ test_add_skip() {

test_expect_success "'ipfs add -r' did not include . files" '
cat >expected <<-\EOF &&
added QmZy3khu7qf696i5HtkgL2NotsCZ8wzvNZJ1eUdA5n8KaV planets/mars.txt
added QmQnv4m3Q5512zgVtpbJ9z85osQrzZzGRn934AGh6iVEXz planets/venus.txt
added QmR8nD1Vzk5twWVC6oShTHvv7mMYkVh6dApCByBJyV2oj3 planets
added QmZy3khu7qf696i5HtkgL2NotsCZ8wzvNZJ1eUdA5n8KaV mountdir/planets/mars.txt
added QmQnv4m3Q5512zgVtpbJ9z85osQrzZzGRn934AGh6iVEXz mountdir/planets/venus.txt
added QmR8nD1Vzk5twWVC6oShTHvv7mMYkVh6dApCByBJyV2oj3 mountdir/planets
added QmPpwRvA6mWE13tFuHNVCZHvUULbhZ1fZFGwtti9BLkwKh mountdir
EOF
test_cmp expected actual
'
Expand All @@ -36,14 +37,15 @@ test_add_skip() {

test_expect_success "'ipfs add -r --hidden' did include . files" '
cat >expected <<-\EOF &&
added QmcAREBcjgnUpKfyFmUGnfajA1NQS5ydqRp7WfqZ6JF8Dx planets/.asteroids/ceres.txt
added QmZ5eaLybJ5GUZBNwy24AA9EEDTDpA4B8qXnuN3cGxu2uF planets/.asteroids/pallas.txt
added QmaowqjedBkUrMUXgzt9c2ZnAJncM9jpJtkFfgdFstGr5a planets/.charon.txt
added QmU4zFD5eJtRBsWC63AvpozM9Atiadg9kPVTuTrnCYJiNF planets/.pluto.txt
added QmZy3khu7qf696i5HtkgL2NotsCZ8wzvNZJ1eUdA5n8KaV planets/mars.txt
added QmQnv4m3Q5512zgVtpbJ9z85osQrzZzGRn934AGh6iVEXz planets/venus.txt
added Qmf6rbs5GF85anDuoxpSAdtuZPM9D2Yt3HngzjUVSQ7kDV planets/.asteroids
added QmetajtFdmzhWYodAsZoVZSiqpeJDAiaw2NwbM3xcWcpDj planets
added QmcAREBcjgnUpKfyFmUGnfajA1NQS5ydqRp7WfqZ6JF8Dx mountdir/planets/.asteroids/ceres.txt
added QmZ5eaLybJ5GUZBNwy24AA9EEDTDpA4B8qXnuN3cGxu2uF mountdir/planets/.asteroids/pallas.txt
added QmaowqjedBkUrMUXgzt9c2ZnAJncM9jpJtkFfgdFstGr5a mountdir/planets/.charon.txt
added QmU4zFD5eJtRBsWC63AvpozM9Atiadg9kPVTuTrnCYJiNF mountdir/planets/.pluto.txt
added QmZy3khu7qf696i5HtkgL2NotsCZ8wzvNZJ1eUdA5n8KaV mountdir/planets/mars.txt
added QmQnv4m3Q5512zgVtpbJ9z85osQrzZzGRn934AGh6iVEXz mountdir/planets/venus.txt
added Qmf6rbs5GF85anDuoxpSAdtuZPM9D2Yt3HngzjUVSQ7kDV mountdir/planets/.asteroids
added QmetajtFdmzhWYodAsZoVZSiqpeJDAiaw2NwbM3xcWcpDj mountdir/planets
added QmXFvBR9SCSEeBeAAvvv8pWzb6ejehsGx7g6XKYg1uYmd5 mountdir
EOF
test_cmp expected actual
'
Expand Down
Loading