github.com/lyeb/hugo@v0.47.1/source/sourceSpec.go (about)

     1  // Copyright 2017-present 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 source
    15  
    16  import (
    17  	"os"
    18  	"path/filepath"
    19  	"regexp"
    20  
    21  	"github.com/gohugoio/hugo/langs"
    22  	"github.com/spf13/afero"
    23  
    24  	"github.com/gohugoio/hugo/helpers"
    25  	"github.com/spf13/cast"
    26  )
    27  
    28  // SourceSpec abstracts language-specific file creation.
    29  // TODO(bep) rename to Spec
    30  type SourceSpec struct {
    31  	*helpers.PathSpec
    32  
    33  	SourceFs afero.Fs
    34  
    35  	// This is set if the ignoreFiles config is set.
    36  	ignoreFilesRe []*regexp.Regexp
    37  
    38  	Languages              map[string]interface{}
    39  	DefaultContentLanguage string
    40  	DisabledLanguages      map[string]bool
    41  }
    42  
    43  // NewSourceSpec initializes SourceSpec using languages the given filesystem and PathSpec.
    44  func NewSourceSpec(ps *helpers.PathSpec, fs afero.Fs) *SourceSpec {
    45  	cfg := ps.Cfg
    46  	defaultLang := cfg.GetString("defaultContentLanguage")
    47  	languages := cfg.GetStringMap("languages")
    48  
    49  	disabledLangsSet := make(map[string]bool)
    50  
    51  	for _, disabledLang := range cfg.GetStringSlice("disableLanguages") {
    52  		disabledLangsSet[disabledLang] = true
    53  	}
    54  
    55  	if len(languages) == 0 {
    56  		l := langs.NewDefaultLanguage(cfg)
    57  		languages[l.Lang] = l
    58  		defaultLang = l.Lang
    59  	}
    60  
    61  	ignoreFiles := cast.ToStringSlice(cfg.Get("ignoreFiles"))
    62  	var regexps []*regexp.Regexp
    63  	if len(ignoreFiles) > 0 {
    64  		for _, ignorePattern := range ignoreFiles {
    65  			re, err := regexp.Compile(ignorePattern)
    66  			if err != nil {
    67  				helpers.DistinctErrorLog.Printf("Invalid regexp %q in ignoreFiles: %s", ignorePattern, err)
    68  			} else {
    69  				regexps = append(regexps, re)
    70  			}
    71  
    72  		}
    73  	}
    74  
    75  	return &SourceSpec{ignoreFilesRe: regexps, PathSpec: ps, SourceFs: fs, Languages: languages, DefaultContentLanguage: defaultLang, DisabledLanguages: disabledLangsSet}
    76  
    77  }
    78  
    79  func (s *SourceSpec) IgnoreFile(filename string) bool {
    80  	if filename == "" {
    81  		if _, ok := s.SourceFs.(*afero.OsFs); ok {
    82  			return true
    83  		}
    84  		return false
    85  	}
    86  
    87  	base := filepath.Base(filename)
    88  
    89  	if len(base) > 0 {
    90  		first := base[0]
    91  		last := base[len(base)-1]
    92  		if first == '.' ||
    93  			first == '#' ||
    94  			last == '~' {
    95  			return true
    96  		}
    97  	}
    98  
    99  	if len(s.ignoreFilesRe) == 0 {
   100  		return false
   101  	}
   102  
   103  	for _, re := range s.ignoreFilesRe {
   104  		if re.MatchString(filename) {
   105  			return true
   106  		}
   107  	}
   108  
   109  	return false
   110  }
   111  
   112  func (s *SourceSpec) IsRegularSourceFile(filename string) (bool, error) {
   113  	fi, err := helpers.LstatIfPossible(s.SourceFs, filename)
   114  	if err != nil {
   115  		return false, err
   116  	}
   117  
   118  	if fi.IsDir() {
   119  		return false, nil
   120  	}
   121  
   122  	if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
   123  		link, err := filepath.EvalSymlinks(filename)
   124  		fi, err = helpers.LstatIfPossible(s.SourceFs, link)
   125  		if err != nil {
   126  			return false, err
   127  		}
   128  
   129  		if fi.IsDir() {
   130  			return false, nil
   131  		}
   132  	}
   133  
   134  	return true, nil
   135  }