github.com/SuCicada/su-hugo@v1.0.0/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  var (
    27  	_ FilesystemUnwrapper = (*filenameFilterFs)(nil)
    28  )
    29  
    30  func newFilenameFilterFs(fs afero.Fs, base string, filter *glob.FilenameFilter) afero.Fs {
    31  	return &filenameFilterFs{
    32  		fs:     fs,
    33  		base:   base,
    34  		filter: filter,
    35  	}
    36  }
    37  
    38  // filenameFilterFs is a filesystem that filters by filename.
    39  type filenameFilterFs struct {
    40  	base string
    41  	fs   afero.Fs
    42  
    43  	filter *glob.FilenameFilter
    44  }
    45  
    46  func (fs *filenameFilterFs) UnwrapFilesystem() afero.Fs {
    47  	return fs.fs
    48  }
    49  
    50  func (fs *filenameFilterFs) LstatIfPossible(name string) (os.FileInfo, bool, error) {
    51  	fi, b, err := fs.fs.(afero.Lstater).LstatIfPossible(name)
    52  	if err != nil {
    53  		return nil, false, err
    54  	}
    55  	if !fs.filter.Match(name, fi.IsDir()) {
    56  		return nil, false, os.ErrNotExist
    57  	}
    58  	return fi, b, nil
    59  }
    60  
    61  func (fs *filenameFilterFs) Open(name string) (afero.File, error) {
    62  	fi, err := fs.fs.Stat(name)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  
    67  	if !fs.filter.Match(name, fi.IsDir()) {
    68  		return nil, os.ErrNotExist
    69  	}
    70  
    71  	f, err := fs.fs.Open(name)
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  
    76  	if !fi.IsDir() {
    77  		return f, nil
    78  	}
    79  
    80  	return &filenameFilterDir{
    81  		File:   f,
    82  		base:   fs.base,
    83  		filter: fs.filter,
    84  	}, nil
    85  }
    86  
    87  func (fs *filenameFilterFs) OpenFile(name string, flag int, perm os.FileMode) (afero.File, error) {
    88  	return fs.Open(name)
    89  }
    90  
    91  func (fs *filenameFilterFs) Stat(name string) (os.FileInfo, error) {
    92  	fi, _, err := fs.LstatIfPossible(name)
    93  	return fi, err
    94  }
    95  
    96  func (fs *filenameFilterFs) getOpener(name string) func() (afero.File, error) {
    97  	return func() (afero.File, error) {
    98  		return fs.Open(name)
    99  	}
   100  }
   101  
   102  type filenameFilterDir struct {
   103  	afero.File
   104  	base   string
   105  	filter *glob.FilenameFilter
   106  }
   107  
   108  func (f *filenameFilterDir) Readdir(count int) ([]os.FileInfo, error) {
   109  	fis, err := f.File.Readdir(-1)
   110  	if err != nil {
   111  		return nil, err
   112  	}
   113  
   114  	var result []os.FileInfo
   115  	for _, fi := range fis {
   116  		fim := fi.(FileMetaInfo)
   117  		if f.filter.Match(strings.TrimPrefix(fim.Meta().Filename, f.base), fim.IsDir()) {
   118  			result = append(result, fi)
   119  		}
   120  	}
   121  
   122  	return result, nil
   123  }
   124  
   125  func (f *filenameFilterDir) Readdirnames(count int) ([]string, error) {
   126  	dirsi, err := f.Readdir(count)
   127  	if err != nil {
   128  		return nil, err
   129  	}
   130  
   131  	dirs := make([]string, len(dirsi))
   132  	for i, d := range dirsi {
   133  		dirs[i] = d.Name()
   134  	}
   135  	return dirs, nil
   136  }
   137  
   138  func (fs *filenameFilterFs) Chmod(n string, m os.FileMode) error {
   139  	return syscall.EPERM
   140  }
   141  
   142  func (fs *filenameFilterFs) Chtimes(n string, a, m time.Time) error {
   143  	return syscall.EPERM
   144  }
   145  
   146  func (fs *filenameFilterFs) Chown(n string, uid, gid int) error {
   147  	return syscall.EPERM
   148  }
   149  
   150  func (fs *filenameFilterFs) ReadDir(name string) ([]os.FileInfo, error) {
   151  	panic("not implemented")
   152  }
   153  
   154  func (fs *filenameFilterFs) Remove(n string) error {
   155  	return syscall.EPERM
   156  }
   157  
   158  func (fs *filenameFilterFs) RemoveAll(p string) error {
   159  	return syscall.EPERM
   160  }
   161  
   162  func (fs *filenameFilterFs) Rename(o, n string) error {
   163  	return syscall.EPERM
   164  }
   165  func (fs *filenameFilterFs) Create(n string) (afero.File, error) {
   166  	return nil, syscall.EPERM
   167  }
   168  func (fs *filenameFilterFs) Name() string {
   169  	return "FinameFilterFS"
   170  }
   171  
   172  func (fs *filenameFilterFs) Mkdir(n string, p os.FileMode) error {
   173  	return syscall.EPERM
   174  }
   175  
   176  func (fs *filenameFilterFs) MkdirAll(n string, p os.FileMode) error {
   177  	return syscall.EPERM
   178  }