Skip to content

Commit

Permalink
feat(kzip tool): use vfs to allow for changing filesystem impl (#3971)
Browse files Browse the repository at this point in the history
  • Loading branch information
justbuchanan committed Aug 8, 2019
1 parent 3ea7de6 commit cb882e9
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 16 deletions.
1 change: 1 addition & 0 deletions kythe/go/platform/tools/kzip/infocmd/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ go_library(
],
deps = [
"//kythe/go/platform/kzip",
"//kythe/go/platform/vfs",
"//kythe/go/util/cmdutil",
"@com_github_google_subcommands//:go_default_library",
"@org_bitbucket_creachadair_stringset//:go_default_library",
Expand Down
4 changes: 2 additions & 2 deletions kythe/go/platform/tools/kzip/infocmd/infocmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ import (
"encoding/json"
"flag"
"fmt"
"os"

"kythe.io/kythe/go/platform/kzip"
"kythe.io/kythe/go/platform/vfs"
"kythe.io/kythe/go/util/cmdutil"

"bitbucket.org/creachadair/stringset"
Expand Down Expand Up @@ -55,7 +55,7 @@ func (c *infoCommand) Execute(ctx context.Context, fs *flag.FlagSet, _ ...interf
if c.input == "" {
return c.Fail("required --input path missing")
}
f, err := os.Open(c.input)
f, err := vfs.Open(ctx, c.input)
if err != nil {
return c.Fail("error opening archive: %v", err)
}
Expand Down
11 changes: 5 additions & 6 deletions kythe/go/platform/tools/kzip/mergecmd/mergecmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@ import (
"fmt"
"io"
"log"
"os"
"path/filepath"

"bitbucket.org/creachadair/stringset"
"kythe.io/kythe/go/platform/kzip"
"kythe.io/kythe/go/platform/tools/kzip/flags"
"kythe.io/kythe/go/platform/vfs"
"kythe.io/kythe/go/util/cmdutil"

"bitbucket.org/creachadair/stringset"
"github.com/google/subcommands"
)

Expand Down Expand Up @@ -108,7 +107,7 @@ func mergeArchives(ctx context.Context, out io.WriteCloser, archives []string, o

filesAdded := stringset.New()
for _, path := range archives {
if err := mergeInto(wr, path, filesAdded); err != nil {
if err := mergeInto(ctx, wr, path, filesAdded); err != nil {
wr.Close()
return err
}
Expand All @@ -120,14 +119,14 @@ func mergeArchives(ctx context.Context, out io.WriteCloser, archives []string, o
return nil
}

func mergeInto(wr *kzip.Writer, path string, filesAdded stringset.Set) error {
f, err := os.Open(path)
func mergeInto(ctx context.Context, wr *kzip.Writer, path string, filesAdded stringset.Set) error {
f, err := vfs.Open(ctx, path)
if err != nil {
return fmt.Errorf("error opening archive: %v", err)
}
defer f.Close()

stat, err := f.Stat()
stat, err := vfs.Stat(ctx, path)
if err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions kythe/go/platform/tools/kzip/viewcmd/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ go_library(
],
deps = [
"//kythe/go/platform/kzip",
"//kythe/go/platform/vfs",
"//kythe/go/util/cmdutil",
"//kythe/proto:buildinfo_go_proto",
"//kythe/proto:cxx_go_proto",
Expand Down
3 changes: 2 additions & 1 deletion kythe/go/platform/tools/kzip/viewcmd/viewcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"time"

"kythe.io/kythe/go/platform/kzip"
"kythe.io/kythe/go/platform/vfs"
"kythe.io/kythe/go/util/cmdutil"

"github.com/golang/protobuf/jsonpb"
Expand Down Expand Up @@ -71,7 +72,7 @@ func (c *cmd) Execute(ctx context.Context, fs *flag.FlagSet, args ...interface{}
ext := filepath.Ext(path)
base := filepath.Base(strings.TrimSuffix(path, ext))

f, err := os.Open(path)
f, err := vfs.Open(ctx, path)
if err != nil {
log.Printf("Error opening .kzip file: %v", err)
hasErrors = true
Expand Down
43 changes: 39 additions & 4 deletions kythe/go/platform/vfs/vfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ type Reader interface {
Stat(ctx context.Context, path string) (os.FileInfo, error)

// Open opens an existing file for reading, as os.Open.
Open(ctx context.Context, path string) (io.ReadCloser, error)
Open(ctx context.Context, path string) (FileReader, error)

// Glob returns all the paths matching the specified glob pattern, as
// filepath.Glob.
Expand Down Expand Up @@ -87,6 +87,14 @@ type Writer interface {
Remove(ctx context.Context, path string) error
}

// FileReader composes interfaces from io that readable files from the vfs must
// implement.
type FileReader interface {
io.ReadCloser
io.ReaderAt
io.Seeker
}

// Default is the global default VFS used by Kythe libraries that wish to access
// the file system. This is usually the LocalFS and should only be changed in
// very specialized cases (i.e. don't change it).
Expand All @@ -112,7 +120,7 @@ func MkdirAll(ctx context.Context, path string, mode os.FileMode) error {
}

// Open opens an existing file for reading, using the Default VFS.
func Open(ctx context.Context, path string) (io.ReadCloser, error) { return Default.Open(ctx, path) }
func Open(ctx context.Context, path string) (FileReader, error) { return Default.Open(ctx, path) }

// Create creates a new file for writing, using the Default VFS.
func Create(ctx context.Context, path string) (io.WriteCloser, error) {
Expand Down Expand Up @@ -151,9 +159,9 @@ func (LocalFS) MkdirAll(_ context.Context, path string, mode os.FileMode) error
}

// Open implements part of the VFS interface.
func (LocalFS) Open(_ context.Context, path string) (io.ReadCloser, error) {
func (LocalFS) Open(_ context.Context, path string) (FileReader, error) {
if path == "-" {
return ioutil.NopCloser(os.Stdin), nil
return stdinWrapper{os.Stdin}, nil
}
return os.Open(path)
}
Expand Down Expand Up @@ -207,3 +215,30 @@ func (UnsupportedWriter) Rename(_ context.Context, _, _ string) error { return E

// Remove implements part of Writer interface. It is not supported.
func (UnsupportedWriter) Remove(_ context.Context, _ string) error { return ErrNotSupported }

// UnseekableFileReader implements the io.Seeker and io.ReaderAt at portion of
// FileReader with stubs that always return ErrNotSupported.
type UnseekableFileReader struct {
io.ReadCloser
}

// ReadAt implements io.ReaderAt interface. It is not supported.
func (UnseekableFileReader) ReadAt([]byte, int64) (int, error) {
return 0, ErrNotSupported
}

// Seek implements io.Seeker interface. It is not supported.
func (UnseekableFileReader) Seek(int64, int) (int64, error) {
return 0, ErrNotSupported
}

// stdinWrapper is similar in purpose to ioutil.NopCloser, but allows access to
// other os.File methods that implement FileReader rather than restricting to
// just ioutil.ReadCloser.
type stdinWrapper struct {
*os.File
}

func (stdinWrapper) Close() error {
return nil
}
10 changes: 7 additions & 3 deletions kythe/go/platform/vfs/zip/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,19 @@ func (z FS) Stat(_ context.Context, path string) (os.FileInfo, error) {
return f.FileInfo(), nil
}

// Open implements part of vfs.Reader, returning a io.ReadCloser owned by
// Open implements part of vfs.Reader, returning a vfs.FileReader owned by
// the underlying zip archive. It is safe to open multiple files concurrently,
// as documented by the zip package.
func (z FS) Open(_ context.Context, path string) (io.ReadCloser, error) {
func (z FS) Open(_ context.Context, path string) (vfs.FileReader, error) {
f := z.find(path)
if f == nil {
return nil, os.ErrNotExist
}
return f.Open()
fo, err := f.Open()
if err != nil {
return nil, err
}
return vfs.UnseekableFileReader{fo}, nil
}

// Glob implements part of vfs.Reader using filepath.Match to compare the
Expand Down

0 comments on commit cb882e9

Please sign in to comment.