github.com/vchain-us/vcn@v0.9.11-0.20210921212052-a2484d23c0b3/pkg/extractor/dir/vcnignore.go (about)

     1  /*
     2   * Copyright (c) 2018-2020 vChain, Inc. All Rights Reserved.
     3   * This software is released under GPL3.
     4   * The full license information can be found under:
     5   * https://www.gnu.org/licenses/gpl-3.0.en.html
     6   *
     7   */
     8  
     9  package dir
    10  
    11  import (
    12  	"io/ioutil"
    13  	"os"
    14  	"path/filepath"
    15  	"strings"
    16  
    17  	"gopkg.in/src-d/go-git.v4/plumbing/format/gitignore"
    18  )
    19  
    20  // IgnoreFilename is the name of the ignore file used by this package when processing directories.
    21  //
    22  // The ignore file supports all pattern formats as specified in the gitignore specification:
    23  //  - https://git-scm.com/docs/gitignore
    24  //  - https://github.com/src-d/go-git/blob/master/plumbing/format/gitignore/doc.go
    25  //
    26  // However, this package implementation:
    27  //  - only uses the ignore file within the root directory (nested ignore files will be treated as normal files)
    28  //  - always ignores the manifest file (it cannot be excluded by the ignore file)
    29  //
    30  const IgnoreFilename = ".vcnignore"
    31  
    32  // DefaultIgnoreFileContent is the content of ignore file with default patterns.
    33  const DefaultIgnoreFileContent = `# Windows thumbnail cache files
    34  Thumbs.db
    35  Thumbs.db:encryptable
    36  ehthumbs.db
    37  ehthumbs_vista.db
    38  
    39  # Windows folder config file
    40  [Dd]esktop.ini
    41  
    42  # Windows Recycle Bin used on file shares
    43  $RECYCLE.BIN/
    44  
    45  # macOS
    46  .DS_Store
    47  .AppleDouble
    48  .LSOverride
    49  
    50  # macOS Thumbnails
    51  ._*
    52  
    53  # macOS files that might appear in the root of a volume
    54  .DocumentRevisions-V100
    55  .fseventsd
    56  .Spotlight-V100
    57  .TemporaryItems
    58  .Trashes
    59  .VolumeIcon.icns
    60  .com.apple.timemachine.donotpresent
    61  
    62  # Directories potentially created on remote AFP share
    63  .AppleDB
    64  .AppleDesktop
    65  Network Trash Folder
    66  Temporary Items
    67  .apdisk
    68  
    69  # temporary files which can be created if a process still has a handle open of a deleted file
    70  .fuse_hidden*
    71  
    72  # KDE directory preferences
    73  .directory
    74  
    75  # Linux trash folder which might appear on any partition or disk
    76  .Trash-*
    77  
    78  # .nfs files are created when an open file is removed but is still being accessed
    79  .nfs*
    80  `
    81  
    82  const (
    83  	ignorefileCommentPrefix = "#"
    84  	ignorefileEOL           = "\n"
    85  )
    86  
    87  type nullMatcher struct{}
    88  
    89  func (n *nullMatcher) Match(path []string, isDir bool) bool {
    90  	return false
    91  }
    92  
    93  // newIgnoreFileMatcher reads and parses the ignore file in path and return a gitignore.Matcher.
    94  // If the ignore file does not exists, a matcher that will never match is returned instead.
    95  func newIgnoreFileMatcher(path string) (m gitignore.Matcher, err error) {
    96  	f, err := os.Open(filepath.Join(path, IgnoreFilename))
    97  	if err != nil {
    98  		if os.IsNotExist(err) {
    99  			return &nullMatcher{}, nil
   100  		}
   101  		return
   102  	}
   103  	defer f.Close()
   104  	ps := []gitignore.Pattern{}
   105  	if data, err := ioutil.ReadAll(f); err == nil {
   106  		for _, s := range strings.Split(string(data), ignorefileEOL) {
   107  			if !strings.HasPrefix(s, ignorefileCommentPrefix) && len(strings.TrimSpace(s)) > 0 {
   108  				ps = append(ps, gitignore.ParsePattern(s, nil))
   109  			}
   110  		}
   111  	}
   112  	m = gitignore.NewMatcher(ps)
   113  	return
   114  }
   115  
   116  // InitIgnoreFile writes the default ignore file if it does not exist.
   117  func InitIgnoreFile(root string) error {
   118  	filename := filepath.Join(root, IgnoreFilename)
   119  
   120  	// create and open the file if not exists
   121  	f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0644)
   122  	if err != nil {
   123  		if os.IsExist(err) {
   124  			return nil // file exists already
   125  		}
   126  		return err
   127  	}
   128  
   129  	// otherwise, write the default content
   130  	_, err = f.WriteString(DefaultIgnoreFileContent)
   131  	return err
   132  }