Skip to content
This repository has been archived by the owner on Mar 29, 2023. It is now read-only.

feat: add WriteTo function #20

Merged
merged 1 commit into from
Aug 16, 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
43 changes: 43 additions & 0 deletions filewriter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package files

import (
"fmt"
"io"
"os"
"path/filepath"
)

// WriteTo writes the given node to the local filesystem at fpath.
func WriteTo(nd Node, fpath string) error {
switch nd := nd.(type) {
case *Symlink:
return os.Symlink(nd.Target, fpath)
case File:
f, err := os.Create(fpath)
defer f.Close()
if err != nil {
return err
}
_, err = io.Copy(f, nd)
if err != nil {
return err
}
return nil
case Directory:
err := os.Mkdir(fpath, 0777)
if err != nil {
return err
}

entries := nd.Entries()
for entries.Next() {
child := filepath.Join(fpath, entries.Name())
if err := WriteTo(entries.Node(), child); err != nil {
return err
}
}
return entries.Err()
default:
return fmt.Errorf("file type %T at %q is not supported", nd, fpath)
}
}
74 changes: 74 additions & 0 deletions filewriter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package files

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
)

func TestWriteTo(t *testing.T) {
sf := NewMapDirectory(map[string]Node{
"1": NewBytesFile([]byte("Some text!\n")),
"2": NewBytesFile([]byte("beep")),
"3": NewMapDirectory(nil),
"4": NewBytesFile([]byte("boop")),
"5": NewMapDirectory(map[string]Node{
"a": NewBytesFile([]byte("foobar")),
}),
})
tmppath, err := ioutil.TempDir("", "files-test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmppath)

path := tmppath + "/output"

err = WriteTo(sf, path)
if err != nil {
t.Fatal(err)
}
expected := map[string]string{
".": "",
"1": "Some text!\n",
"2": "beep",
"3": "",
"4": "boop",
"5": "",
"5/a": "foobar",
}
err = filepath.Walk(path, func(cpath string, info os.FileInfo, err error) error {
rpath, err := filepath.Rel(path, cpath)
if err != nil {
return err
}
data, ok := expected[rpath]
if !ok {
return fmt.Errorf("expected something at %q", rpath)
}
delete(expected, rpath)

if info.IsDir() {
if data != "" {
return fmt.Errorf("expected a directory at %q", rpath)
}
} else {
actual, err := ioutil.ReadFile(cpath)
if err != nil {
return err
}
if string(actual) != data {
return fmt.Errorf("expected %q, got %q", data, string(actual))
}
}
return nil
})
if err != nil {
t.Fatal(err)
}
if len(expected) > 0 {
t.Fatalf("failed to find: %#v", expected)
}
}