github.com/graemephi/kahugo@v0.62.3-0.20211121071557-d78c0423784d/hugofs/filename_filter_fs.go (about)

     1  // Copyright 2021 The Hugo Authors. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package hugofs
    15  
    16  import (
    17  	"os"
    18  	"strings"
    19  	"syscall"
    20  	"time"
    21  
    22  	"github.com/gohugoio/hugo/hugofs/glob"
    23  	"github.com/spf13/afero"
    24  )
    25  
    26  func newFilenameFilterFs(fs afero.Fs, base string, filter *glob.FilenameFilter) afero.Fs {
    27  	return &filenameFilterFs{
    28  		fs:     fs,
    29  		base:   base,
    30  		filter: filter,
    31  	}
    32  }
    33  
    34  // filenameFilterFs is a filesystem that filters by filename.
    35  type filenameFilterFs struct {
    36  	base string
    37  	fs   afero.Fs
    38  
    39  	filter *glob.FilenameFilter
    40  }
    41  
    42  func (fs *filenameFilterFs) LstatIfPossible(name string) (os.FileInfo, bool, error) {
    43  	fi, b, err := fs.fs.(afero.Lstater).LstatIfPossible(name)
    44  	if err != nil {
    45  		return nil, false, err
    46  	}
    47  	if !fs.filter.Match(name, fi.IsDir()) {
    48  		return nil, false, os.ErrNotExist
    49  	}
    50  	return fi, b, nil
    51  }
    52  
    53  func (fs *filenameFilterFs) Open(name string) (afero.File, error) {
    54  	fi, err := fs.fs.Stat(name)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  
    59  	if !fs.filter.Match(name, fi.IsDir()) {
    60  		return nil, os.ErrNotExist
    61  	}
    62  
    63  	f, err := fs.fs.Open(name)
    64  	if err != nil {
    65  		return nil, err
    66  	}
    67  
    68  	if !fi.IsDir() {
    69  		return f, nil
    70  	}
    71  
    72  	return &filenameFilterDir{
    73  		File:   f,
    74  		base:   fs.base,
    75  		filter: fs.filter,
    76  	}, nil
    77  }
    78  
    79  func (fs *filenameFilterFs) OpenFile(name string, flag int, perm os.FileMode) (afero.File, error) {
    80  	return fs.Open(name)
    81  }
    82  
    83  func (fs *filenameFilterFs) Stat(name string) (os.FileInfo, error) {
    84  	fi, _, err := fs.LstatIfPossible(name)
    85  	return fi, err
    86  }
    87  
    88  func (fs *filenameFilterFs) getOpener(name string) func() (afero.File, error) {
    89  	return func() (afero.File, error) {
    90  		return fs.Open(name)
    91  	}
    92  }
    93  
    94  type filenameFilterDir struct {
    95  	afero.File
    96  	base   string
    97  	filter *glob.FilenameFilter
    98  }
    99  
   100  func (f *filenameFilterDir) Readdir(count int) ([]os.FileInfo, error) {
   101  	fis, err := f.File.Readdir(-1)
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  
   106  	var result []os.FileInfo
   107  	for _, fi := range fis {
   108  		fim := fi.(FileMetaInfo)
   109  		if f.filter.Match(strings.TrimPrefix(fim.Meta().Filename, f.base), fim.IsDir()) {
   110  			result = append(result, fi)
   111  		}
   112  	}
   113  
   114  	return result, nil
   115  }
   116  
   117  func (f *filenameFilterDir) Readdirnames(count int) ([]string, error) {
   118  	dirsi, err := f.Readdir(count)
   119  	if err != nil {
   120  		return nil, err
   121  	}
   122  
   123  	dirs := make([]string, len(dirsi))
   124  	for i, d := range dirsi {
   125  		dirs[i] = d.Name()
   126  	}
   127  	return dirs, nil
   128  }
   129  
   130  func (fs *filenameFilterFs) Chmod(n string, m os.FileMode) error {
   131  	return syscall.EPERM
   132  }
   133  
   134  func (fs *filenameFilterFs) Chtimes(n string, a, m time.Time) error {
   135  	return syscall.EPERM
   136  }
   137  
   138  func (fs *filenameFilterFs) Chown(n string, uid, gid int) error {
   139  	return syscall.EPERM
   140  }
   141  
   142  func (fs *filenameFilterFs) ReadDir(name string) ([]os.FileInfo, error) {
   143  	panic("not implemented")
   144  }
   145  
   146  func (fs *filenameFilterFs) Remove(n string) error {
   147  	return syscall.EPERM
   148  }
   149  
   150  func (fs *filenameFilterFs) RemoveAll(p string) error {
   151  	return syscall.EPERM
   152  }
   153  
   154  func (fs *filenameFilterFs) Rename(o, n string) error {
   155  	return syscall.EPERM
   156  }
   157  func (fs *filenameFilterFs) Create(n string) (afero.File, error) {
   158  	return nil, syscall.EPERM
   159  }
   160  func (fs *filenameFilterFs) Name() string {
   161  	return "FinameFilterFS"
   162  }
   163  
   164  func (fs *filenameFilterFs) Mkdir(n string, p os.FileMode) error {
   165  	return syscall.EPERM
   166  }
   167  
   168  func (fs *filenameFilterFs) MkdirAll(n string, p os.FileMode) error {
   169  	return syscall.EPERM
   170  }