aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com')
-rw-r--r--vendor/github.com/shurcooL/httpfs/filter/filter.go133
-rw-r--r--vendor/github.com/shurcooL/httpfs/filter/filters.go26
2 files changed, 159 insertions, 0 deletions
diff --git a/vendor/github.com/shurcooL/httpfs/filter/filter.go b/vendor/github.com/shurcooL/httpfs/filter/filter.go
new file mode 100644
index 00000000..6f03e597
--- /dev/null
+++ b/vendor/github.com/shurcooL/httpfs/filter/filter.go
@@ -0,0 +1,133 @@
+// Package filter offers an http.FileSystem wrapper with the ability to keep or skip files.
+package filter
+
+import (
+ "fmt"
+ "io"
+ "net/http"
+ "os"
+ pathpkg "path"
+ "time"
+)
+
+// Func is a selection function which is provided two arguments,
+// its '/'-separated cleaned rooted absolute path (i.e., it always begins with "/"),
+// and the os.FileInfo of the considered file.
+//
+// The path is cleaned via pathpkg.Clean("/" + path).
+//
+// For example, if the considered file is named "a" and it's inside a directory "dir",
+// then the value of path will be "/dir/a".
+type Func func(path string, fi os.FileInfo) bool
+
+// Keep returns a filesystem that contains only those entries in source for which
+// keep returns true.
+func Keep(source http.FileSystem, keep Func) http.FileSystem {
+ return &filterFS{source: source, keep: keep}
+}
+
+// Skip returns a filesystem that contains everything in source, except entries
+// for which skip returns true.
+func Skip(source http.FileSystem, skip Func) http.FileSystem {
+ keep := func(path string, fi os.FileInfo) bool {
+ return !skip(path, fi)
+ }
+ return &filterFS{source: source, keep: keep}
+}
+
+type filterFS struct {
+ source http.FileSystem
+ keep Func // Keep entries that keep returns true for.
+}
+
+func (fs *filterFS) Open(path string) (http.File, error) {
+ f, err := fs.source.Open(path)
+ if err != nil {
+ return nil, err
+ }
+
+ fi, err := f.Stat()
+ if err != nil {
+ f.Close()
+ return nil, err
+ }
+
+ if !fs.keep(clean(path), fi) {
+ // Skip.
+ f.Close()
+ return nil, &os.PathError{Op: "open", Path: path, Err: os.ErrNotExist}
+ }
+
+ if !fi.IsDir() {
+ return f, nil
+ }
+ defer f.Close()
+
+ fis, err := f.Readdir(0)
+ if err != nil {
+ return nil, err
+ }
+
+ var entries []os.FileInfo
+ for _, fi := range fis {
+ if !fs.keep(clean(pathpkg.Join(path, fi.Name())), fi) {
+ // Skip.
+ continue
+ }
+ entries = append(entries, fi)
+ }
+
+ return &dir{
+ name: fi.Name(),
+ entries: entries,
+ modTime: fi.ModTime(),
+ }, nil
+}
+
+// clean turns a potentially relative path into an absolute one.
+//
+// This is needed to normalize path parameter for selection function.
+func clean(path string) string {
+ return pathpkg.Clean("/" + path)
+}
+
+// dir is an opened dir instance.
+type dir struct {
+ name string
+ modTime time.Time
+ entries []os.FileInfo
+ pos int // Position within entries for Seek and Readdir.
+}
+
+func (d *dir) Read([]byte) (int, error) {
+ return 0, fmt.Errorf("cannot Read from directory %s", d.name)
+}
+func (d *dir) Close() error { return nil }
+func (d *dir) Stat() (os.FileInfo, error) { return d, nil }
+
+func (d *dir) Name() string { return d.name }
+func (d *dir) Size() int64 { return 0 }
+func (d *dir) Mode() os.FileMode { return 0755 | os.ModeDir }
+func (d *dir) ModTime() time.Time { return d.modTime }
+func (d *dir) IsDir() bool { return true }
+func (d *dir) Sys() interface{} { return nil }
+
+func (d *dir) Seek(offset int64, whence int) (int64, error) {
+ if offset == 0 && whence == io.SeekStart {
+ d.pos = 0
+ return 0, nil
+ }
+ return 0, fmt.Errorf("unsupported Seek in directory %s", d.name)
+}
+
+func (d *dir) Readdir(count int) ([]os.FileInfo, error) {
+ if d.pos >= len(d.entries) && count > 0 {
+ return nil, io.EOF
+ }
+ if count <= 0 || count > len(d.entries)-d.pos {
+ count = len(d.entries) - d.pos
+ }
+ e := d.entries[d.pos : d.pos+count]
+ d.pos += count
+ return e, nil
+}
diff --git a/vendor/github.com/shurcooL/httpfs/filter/filters.go b/vendor/github.com/shurcooL/httpfs/filter/filters.go
new file mode 100644
index 00000000..a20edaf4
--- /dev/null
+++ b/vendor/github.com/shurcooL/httpfs/filter/filters.go
@@ -0,0 +1,26 @@
+package filter
+
+import (
+ "os"
+ pathpkg "path"
+)
+
+// FilesWithExtensions returns a filter func that selects files (but not directories)
+// that have any of the given extensions. For example:
+//
+// filter.FilesWithExtensions(".go", ".html")
+//
+// Would select both .go and .html files. It would not select any directories.
+func FilesWithExtensions(exts ...string) Func {
+ return func(path string, fi os.FileInfo) bool {
+ if fi.IsDir() {
+ return false
+ }
+ for _, ext := range exts {
+ if pathpkg.Ext(path) == ext {
+ return true
+ }
+ }
+ return false
+ }
+}