1
0
mirror of https://github.com/danog/gojekyll.git synced 2024-11-27 00:34:42 +01:00

Refine file exclusion

This commit is contained in:
Oliver Steele 2017-07-27 18:07:42 -04:00
parent b51cd1b295
commit b789096b3a
6 changed files with 68 additions and 45 deletions

View File

@ -21,13 +21,13 @@ func readTestSiteDrop(t *testing.T) map[string]interface{} {
func TestSite_ToLiquid(t *testing.T) { func TestSite_ToLiquid(t *testing.T) {
drop := readTestSiteDrop(t) drop := readTestSiteDrop(t)
docs, isTime := drop["documents"].([]pages.Document) docs, ok := drop["documents"].([]pages.Document)
require.True(t, isTime, fmt.Sprintf("documents has type %T", drop["documents"])) require.True(t, ok, fmt.Sprintf("documents has type %T", drop["documents"]))
require.Len(t, docs, 4) require.Len(t, docs, 4)
} }
func TestSite_ToLiquid_time(t *testing.T) { func TestSite_ToLiquid_time(t *testing.T) {
drop := readTestSiteDrop(t) drop := readTestSiteDrop(t)
_, ok := drop["time"].(time.Time) _, ok := drop["time"].(time.Time)
require.True(t, ok) require.True(t, ok)

View File

@ -3,6 +3,7 @@ package site
import ( import (
"os" "os"
"path/filepath" "path/filepath"
"strings"
"github.com/osteele/gojekyll/collection" "github.com/osteele/gojekyll/collection"
"github.com/osteele/gojekyll/config" "github.com/osteele/gojekyll/config"
@ -56,7 +57,11 @@ func (s *Site) readFiles(dir, base string) error {
switch { switch {
case info.IsDir() && s.Exclude(rel): case info.IsDir() && s.Exclude(rel):
return filepath.SkipDir return filepath.SkipDir
case info.IsDir(), s.Exclude(rel): case info.IsDir():
return nil
case s.Exclude(rel):
return nil
case strings.HasPrefix(rel, "_"):
return nil return nil
} }
defaultFrontmatter := s.config.GetFrontMatterDefaults("", rel) defaultFrontmatter := s.config.GetFrontMatterDefaults("", rel)

View File

@ -3,7 +3,6 @@ package site
import ( import (
"fmt" "fmt"
"os" "os"
"path/filepath"
"strings" "strings"
"time" "time"
@ -130,7 +129,7 @@ loop:
switch { switch {
case s.config.IsConfigPath(path): case s.config.IsConfigPath(path):
// break // break
case !s.fileAffectsBuild(path): case s.Exclude(path):
continue loop continue loop
case seen[path]: case seen[path]:
continue loop continue loop
@ -141,25 +140,6 @@ loop:
return result return result
} }
// Returns true if the file or a parent directory is excluded.
// Cf. Site.Exclude.
func (s *Site) fileAffectsBuild(rel string) bool {
for rel != "" {
switch {
case rel == ".":
return true
case utils.MatchList(s.config.Include, rel):
return true
case utils.MatchList(s.config.Exclude, rel):
return false
case strings.HasPrefix(rel, "."):
return false
}
rel = filepath.Dir(rel)
}
return true
}
// returns true if changes to the site-relative paths invalidate doc // returns true if changes to the site-relative paths invalidate doc
func (s *Site) invalidatesDoc(paths map[string]bool, d pages.Document) bool { func (s *Site) invalidatesDoc(paths map[string]bool, d pages.Document) bool {
rel := utils.MustRel(s.SourceDir(), d.SourcePath()) rel := utils.MustRel(s.SourceDir(), d.SourcePath())

View File

@ -3,7 +3,7 @@ package site
import ( import (
"fmt" "fmt"
"path/filepath" "path/filepath"
"strings" "regexp"
"sync" "sync"
"github.com/osteele/gojekyll/collection" "github.com/osteele/gojekyll/collection"
@ -205,23 +205,26 @@ func (s *Site) URLPage(urlpath string) (p pages.Document, found bool) {
return return
} }
var excludeFileRE = regexp.MustCompile(`^[#~]|^\..|~$`)
// Exclude returns a boolean indicating that the site configuration excludes a file or directory. // Exclude returns a boolean indicating that the site configuration excludes a file or directory.
// This function just looks at the base name: it doesn't recognize that a file in an // It does not exclude top-level _underscore files and directories.
// excluded directory is therefore excluded. It also excludes files in _includes, _sass, and _{container}, etc. func (s *Site) Exclude(siteRel string) bool {
// which aren't copied to the destination but do affect the build. for siteRel != "." {
// Cf. Site.fileAffectsBuild. dir, base := filepath.Dir(siteRel), filepath.Base(siteRel)
func (s *Site) Exclude(path string) bool { switch {
base := filepath.Base(path) case utils.MatchList(s.config.Include, siteRel):
switch { return false
case path == ".": case utils.MatchList(s.config.Exclude, siteRel):
return false return true
case utils.MatchList(s.config.Include, base): case dir != "." && base[0] == '_':
return false return true
case utils.MatchList(s.config.Exclude, base): default:
return true if excludeFileRE.MatchString(base) {
case strings.HasPrefix(base, "."), strings.HasPrefix(base, "_"): return true
return true }
default: }
return false siteRel = dir
} }
return false
} }

View File

@ -7,10 +7,40 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestIsMarkdown(t *testing.T) { func TestKeepFile(t *testing.T) {
s := New(config.Flags{}) s := New(config.Flags{})
require.Equal(t, "", s.PathPrefix()) require.Equal(t, "", s.PathPrefix())
require.False(t, s.KeepFile("random")) require.False(t, s.KeepFile("random"))
require.True(t, s.KeepFile(".git")) require.True(t, s.KeepFile(".git"))
require.True(t, s.KeepFile(".svn")) require.True(t, s.KeepFile(".svn"))
} }
func TestExclude(t *testing.T) {
s := New(config.Flags{})
s.config.Exclude = append(s.config.Exclude, "exclude/")
s.config.Include = append(s.config.Include, ".include/")
require.False(t, s.Exclude("."))
require.True(t, s.Exclude(".git"))
require.True(t, s.Exclude(".dir"))
require.True(t, s.Exclude(".dir/file"))
require.False(t, s.Exclude(".htaccess"))
require.False(t, s.Exclude("dir"))
require.False(t, s.Exclude("dir/file"))
require.True(t, s.Exclude("dir/.file"))
require.True(t, s.Exclude("dir/#file"))
require.True(t, s.Exclude("dir/~file"))
require.True(t, s.Exclude("dir/file~"))
require.True(t, s.Exclude("dir/subdir/.file"))
require.False(t, s.Exclude(".include/file"))
require.True(t, s.Exclude("exclude/file"))
require.False(t, s.Exclude("_posts"))
require.False(t, s.Exclude("_posts/file"))
require.True(t, s.Exclude("_posts/_file"))
require.True(t, s.Exclude("_posts/_dir/file"))
// The following aren't documented but are evident
// TODO submit a doc PR to Jekyll
require.True(t, s.Exclude("#file"))
require.True(t, s.Exclude("~file"))
require.True(t, s.Exclude("file~"))
}

View File

@ -15,8 +15,10 @@ func FilenameDate(s string) (time.Time, bool) {
return t, err == nil return t, err == nil
} }
// MatchList reports whether any glob pattern matches the path. // MatchList implement Jekyll include: and exclude: configurations.
// It reports whether any glob pattern matches the path.
// It panics with ErrBadPattern if any pattern is malformed. // It panics with ErrBadPattern if any pattern is malformed.
// To match Jekyll, a string "dir/" matches that begins with this prefix.
func MatchList(patterns []string, name string) bool { func MatchList(patterns []string, name string) bool {
for _, p := range patterns { for _, p := range patterns {
match, err := filepath.Match(p, name) match, err := filepath.Match(p, name)
@ -26,6 +28,9 @@ func MatchList(patterns []string, name string) bool {
if match { if match {
return true return true
} }
if strings.HasSuffix(p, "/") && strings.HasPrefix(name, p) {
return true
}
} }
return false return false
} }