createcounting_fs.go - hugo - [fork] hugo port for 9front
 (HTM) git clone https://git.drkhsh.at/hugo.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
 (DIR) README
 (DIR) LICENSE
       ---
       createcounting_fs.go (2369B)
       ---
            1 // Copyright 2019 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         "fmt"
           18         "os"
           19         "sort"
           20         "strings"
           21         "sync"
           22 
           23         "github.com/spf13/afero"
           24 )
           25 
           26 // Reseter is implemented by some of the stateful filesystems.
           27 type Reseter interface {
           28         Reset()
           29 }
           30 
           31 // DuplicatesReporter reports about duplicate filenames.
           32 type DuplicatesReporter interface {
           33         ReportDuplicates() string
           34 }
           35 
           36 var _ FilesystemUnwrapper = (*createCountingFs)(nil)
           37 
           38 func NewCreateCountingFs(fs afero.Fs) afero.Fs {
           39         return &createCountingFs{Fs: fs, fileCount: make(map[string]int)}
           40 }
           41 
           42 func (fs *createCountingFs) UnwrapFilesystem() afero.Fs {
           43         return fs.Fs
           44 }
           45 
           46 // ReportDuplicates reports filenames written more than once.
           47 func (c *createCountingFs) ReportDuplicates() string {
           48         c.mu.Lock()
           49         defer c.mu.Unlock()
           50 
           51         var dupes []string
           52 
           53         for k, v := range c.fileCount {
           54                 if v > 1 {
           55                         dupes = append(dupes, fmt.Sprintf("%s (%d)", k, v))
           56                 }
           57         }
           58 
           59         if len(dupes) == 0 {
           60                 return ""
           61         }
           62 
           63         sort.Strings(dupes)
           64 
           65         return strings.Join(dupes, ", ")
           66 }
           67 
           68 // createCountingFs counts filenames of created files or files opened
           69 // for writing.
           70 type createCountingFs struct {
           71         afero.Fs
           72 
           73         mu        sync.Mutex
           74         fileCount map[string]int
           75 }
           76 
           77 func (c *createCountingFs) Reset() {
           78         c.mu.Lock()
           79         defer c.mu.Unlock()
           80 
           81         c.fileCount = make(map[string]int)
           82 }
           83 
           84 func (fs *createCountingFs) onCreate(filename string) {
           85         fs.mu.Lock()
           86         defer fs.mu.Unlock()
           87 
           88         fs.fileCount[filename] = fs.fileCount[filename] + 1
           89 }
           90 
           91 func (fs *createCountingFs) Create(name string) (afero.File, error) {
           92         f, err := fs.Fs.Create(name)
           93         if err == nil {
           94                 fs.onCreate(name)
           95         }
           96         return f, err
           97 }
           98 
           99 func (fs *createCountingFs) OpenFile(name string, flag int, perm os.FileMode) (afero.File, error) {
          100         f, err := fs.Fs.OpenFile(name, flag, perm)
          101         if err == nil && isWrite(flag) {
          102                 fs.onCreate(name)
          103         }
          104         return f, err
          105 }