From 4c81634ab74ea14f25b2dffa672cb9c84ef4e762 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Mon, 27 Jun 2022 11:04:33 +0800 Subject: [PATCH 1/4] =?UTF-8?q?:art:=20=E5=90=8C=E6=AD=A5=E5=BF=BD?= =?UTF-8?q?=E7=95=A5=E6=96=87=E4=BB=B6=E9=85=8D=E7=BD=AE=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=20gitignore=20=E8=A7=84=E5=88=99=20https://github.com/siyuan-n?= =?UTF-8?q?ote/siyuan/issues/5295?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/go.mod | 1 + kernel/go.sum | 2 + kernel/model/sync.go | 50 +++-------- kernel/util/ignore.go | 204 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 220 insertions(+), 37 deletions(-) create mode 100644 kernel/util/ignore.go diff --git a/kernel/go.mod b/kernel/go.mod index ecf870841..1f254ec6c 100644 --- a/kernel/go.mod +++ b/kernel/go.mod @@ -93,6 +93,7 @@ require ( github.com/pelletier/go-toml/v2 v2.0.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/restic/chunker v0.4.0 // indirect + github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/ugorji/go/codec v1.2.7 // indirect diff --git a/kernel/go.sum b/kernel/go.sum index 6b133fd66..899b5363f 100644 --- a/kernel/go.sum +++ b/kernel/go.sum @@ -409,6 +409,8 @@ github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUA github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI= +github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs= github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= diff --git a/kernel/model/sync.go b/kernel/model/sync.go index 7838aeb9b..e54b24fb8 100644 --- a/kernel/model/sync.go +++ b/kernel/model/sync.go @@ -34,8 +34,7 @@ import ( "github.com/88250/gulu" "github.com/dustin/go-humanize" - "github.com/emirpasic/gods/sets/hashset" - "github.com/mattn/go-zglob" + gitignore "github.com/sabhiram/go-gitignore" "github.com/siyuan-note/encryption" "github.com/siyuan-note/filelock" "github.com/siyuan-note/siyuan/kernel/cache" @@ -1253,9 +1252,8 @@ func IsValidCloudDirName(cloudDirName string) bool { func getSyncExcludedList(localDirPath string) (ret map[string]bool) { syncIgnoreList := getSyncIgnoreList() ret = map[string]bool{} - ignores := syncIgnoreList.Values() - for _, p := range ignores { - relPath := p.(string) + for _, p := range syncIgnoreList { + relPath := p relPath = pathSha256Short(relPath, "/") relPath = filepath.Join(localDirPath, relPath) ret[relPath] = true @@ -1263,8 +1261,7 @@ func getSyncExcludedList(localDirPath string) (ret map[string]bool) { return } -func getSyncIgnoreList() (ret *hashset.Set) { - ret = hashset.New() +func getSyncIgnoreList() (ret []string) { ignore := filepath.Join(util.DataDir, ".siyuan", "syncignore") os.MkdirAll(filepath.Dir(ignore), 0755) if !gulu.File.IsExist(ignore) { @@ -1287,37 +1284,16 @@ func getSyncIgnoreList() (ret *hashset.Set) { lines = append(lines, "20210808180117-czj9bvb/**/*") lines = append(lines, "20211226090932-5lcq56f/**/*") - var parents []string - for _, line := range lines { - if idx := strings.Index(line, "/*"); -1 < idx { - parent := line[:idx] - parents = append(parents, parent) + lines = gulu.Str.RemoveDuplicatedElem(lines) + gi := gitignore.CompileIgnoreLines(lines...) + filepath.Walk(util.DataDir, func(p string, info os.FileInfo, err error) error { + p = strings.TrimPrefix(p, util.DataDir+string(os.PathSeparator)) + p = filepath.ToSlash(p) + if gi.MatchesPath(p) { + ret = append(ret, p) } - } - lines = append(lines, parents...) - - for _, line := range lines { - line = strings.TrimSpace(line) - if "" == line { - continue - } - pattern := filepath.Join(util.DataDir, line) - pattern = filepath.FromSlash(pattern) - matches, globErr := zglob.Glob(pattern) - if nil != globErr && globErr != os.ErrNotExist { - util.LogErrorf("glob [%s] failed: %s", line, globErr) - continue - } - for _, m := range matches { - m = filepath.ToSlash(m) - if strings.Contains(m, ".siyuan/history") { - continue - } - - m = strings.TrimPrefix(m, filepath.ToSlash(util.DataDir+string(os.PathSeparator))) - ret.Add(m) - } - } + return nil + }) return } diff --git a/kernel/util/ignore.go b/kernel/util/ignore.go new file mode 100644 index 000000000..942d4d646 --- /dev/null +++ b/kernel/util/ignore.go @@ -0,0 +1,204 @@ +// SiYuan - Build Your Eternal Digital Garden +// Copyright (c) 2020-present, b3log.org +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package util + +// 该文件代码来自 https://github.com/go-git/go-git 项目,Apache-2.0 license + +import ( + "path/filepath" + "strings" +) + +// https://github.com/go-git/go-git/blob/master/plumbing/format/gitignore/matcher.go + +// Matcher defines a global multi-pattern matcher for gitignore patterns +type Matcher interface { + // Match matches patterns in the order of priorities. As soon as an inclusion or + // exclusion is found, not further matching is performed. + Match(path []string, isDir bool) bool +} + +// NewMatcher constructs a new global matcher. Patterns must be given in the order of +// increasing priority. That is most generic settings files first, then the content of +// the repo .gitignore, then content of .gitignore down the path or the repo and then +// the content command line arguments. +func NewMatcher(ps []Pattern) Matcher { + return &matcher{ps} +} + +type matcher struct { + patterns []Pattern +} + +func (m *matcher) Match(path []string, isDir bool) bool { + n := len(m.patterns) + for i := n - 1; i >= 0; i-- { + if match := m.patterns[i].Match(path, isDir); match > NoMatch { + return match == Exclude + } + } + return false +} + +// https://github.com/go-git/go-git/blob/master/plumbing/format/gitignore/pattern.go + +// MatchResult defines outcomes of a match, no match, exclusion or inclusion. +type MatchResult int + +const ( + // NoMatch defines the no match outcome of a match check + NoMatch MatchResult = iota + // Exclude defines an exclusion of a file as a result of a match check + Exclude + // Include defines an explicit inclusion of a file as a result of a match check + Include +) + +const ( + inclusionPrefix = "!" + zeroToManyDirs = "**" + patternDirSep = "/" +) + +// Pattern defines a single gitignore pattern. +type Pattern interface { + // Match matches the given path to the pattern. + Match(path []string, isDir bool) MatchResult +} + +type pattern struct { + domain []string + pattern []string + inclusion bool + dirOnly bool + isGlob bool +} + +// ParsePattern parses a gitignore pattern string into the Pattern structure. +func ParsePattern(p string, domain []string) Pattern { + res := pattern{domain: domain} + + if strings.HasPrefix(p, inclusionPrefix) { + res.inclusion = true + p = p[1:] + } + + if !strings.HasSuffix(p, "\\ ") { + p = strings.TrimRight(p, " ") + } + + if strings.HasSuffix(p, patternDirSep) { + res.dirOnly = true + p = p[:len(p)-1] + } + + if strings.Contains(p, patternDirSep) { + res.isGlob = true + } + + res.pattern = strings.Split(p, patternDirSep) + return &res +} + +func (p *pattern) Match(path []string, isDir bool) MatchResult { + if len(path) <= len(p.domain) { + return NoMatch + } + for i, e := range p.domain { + if path[i] != e { + return NoMatch + } + } + + path = path[len(p.domain):] + if p.isGlob && !p.globMatch(path, isDir) { + return NoMatch + } else if !p.isGlob && !p.simpleNameMatch(path, isDir) { + return NoMatch + } + + if p.inclusion { + return Include + } else { + return Exclude + } +} + +func (p *pattern) simpleNameMatch(path []string, isDir bool) bool { + for i, name := range path { + if match, err := filepath.Match(p.pattern[0], name); err != nil { + return false + } else if !match { + continue + } + if p.dirOnly && !isDir && i == len(path)-1 { + return false + } + return true + } + return false +} + +func (p *pattern) globMatch(path []string, isDir bool) bool { + matched := false + canTraverse := false + for i, pattern := range p.pattern { + if pattern == "" { + canTraverse = false + continue + } + if pattern == zeroToManyDirs { + if i == len(p.pattern)-1 { + break + } + canTraverse = true + continue + } + if strings.Contains(pattern, zeroToManyDirs) { + return false + } + if len(path) == 0 { + return false + } + if canTraverse { + canTraverse = false + for len(path) > 0 { + e := path[0] + path = path[1:] + if match, err := filepath.Match(pattern, e); err != nil { + return false + } else if match { + matched = true + break + } else if len(path) == 0 { + // if nothing left then fail + matched = false + } + } + } else { + if match, err := filepath.Match(pattern, path[0]); err != nil || !match { + return false + } + matched = true + path = path[1:] + } + } + if matched && p.dirOnly && !isDir && len(path) == 0 { + matched = false + } + return matched +} From 070f51a3ab1168e2b8997a98d711072a765719dd Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Mon, 27 Jun 2022 11:24:20 +0800 Subject: [PATCH 2/4] =?UTF-8?q?:art:=20=E5=90=8C=E6=AD=A5=E5=BF=BD?= =?UTF-8?q?=E7=95=A5=E6=96=87=E4=BB=B6=E9=85=8D=E7=BD=AE=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=20gitignore=20=E8=A7=84=E5=88=99=20https://github.com/siyuan-n?= =?UTF-8?q?ote/siyuan/issues/5295?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- README_zh_CN.md | 2 +- kernel/go.mod | 3 +- kernel/go.sum | 4 - kernel/model/import.go | 30 +++--- kernel/util/ignore.go | 204 ----------------------------------------- 6 files changed, 18 insertions(+), 227 deletions(-) delete mode 100644 kernel/util/ignore.go diff --git a/README.md b/README.md index 4287712a1..5b3c0a802 100644 --- a/README.md +++ b/README.md @@ -282,12 +282,12 @@ SiYuan is made possible by the following open source projects. * [https://github.com/imroc/req](https://github.com/imroc/req) `MIT License` * [https://github.com/jinzhu/copier](https://github.com/jinzhu/copier) `MIT License` * [https://github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) `MIT License` -* [https://github.com/mattn/go-zglob](https://github.com/mattn/go-zglob) `MIT License` * [https://github.com/mitchellh/go-ps](https://github.com/mitchellh/go-ps) `MIT License` * [https://github.com/mssola/user_agent](https://github.com/mssola/user_agent) `MIT License` * [https://github.com/panjf2000/ants](https://github.com/panjf2000/ants) `MIT License` * [https://github.com/patrickmn/go-cache](https://github.com/patrickmn/go-cache) `MIT License` * [https://github.com/radovskyb/watcher](https://github.com/radovskyb/watcher) `BSD-3-Clause License` +* [https://github.com/sabhiram/go-gitignore](https://github.com/sabhiram/go-gitignore) `MIT License` * [https://github.com/siyuan-note/dejavu](https://github.com/siyuan-note/dejavu) `Mulan PSL v2` * [https://github.com/siyuan-note/encryption](https://github.com/siyuan-note/encryption) `Mulan PSL v2` * [https://github.com/siyuan-note/filelock](https://github.com/siyuan-note/filelock) `Mulan PSL v2` diff --git a/README_zh_CN.md b/README_zh_CN.md index ab9388429..d6ae72435 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -291,12 +291,12 @@ * [https://github.com/imroc/req](https://github.com/imroc/req) `MIT License` * [https://github.com/jinzhu/copier](https://github.com/jinzhu/copier) `MIT License` * [https://github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) `MIT License` -* [https://github.com/mattn/go-zglob](https://github.com/mattn/go-zglob) `MIT License` * [https://github.com/mitchellh/go-ps](https://github.com/mitchellh/go-ps) `MIT License` * [https://github.com/mssola/user_agent](https://github.com/mssola/user_agent) `MIT License` * [https://github.com/panjf2000/ants](https://github.com/panjf2000/ants) `MIT License` * [https://github.com/patrickmn/go-cache](https://github.com/patrickmn/go-cache) `MIT License` * [https://github.com/radovskyb/watcher](https://github.com/radovskyb/watcher) `BSD-3-Clause License` +* [https://github.com/sabhiram/go-gitignore](https://github.com/sabhiram/go-gitignore) `MIT License` * [https://github.com/siyuan-note/dejavu](https://github.com/siyuan-note/dejavu) `Mulan PSL v2` * [https://github.com/siyuan-note/encryption](https://github.com/siyuan-note/encryption) `Mulan PSL v2` * [https://github.com/siyuan-note/filelock](https://github.com/siyuan-note/filelock) `Mulan PSL v2` diff --git a/kernel/go.mod b/kernel/go.mod index 1f254ec6c..a1ddea600 100644 --- a/kernel/go.mod +++ b/kernel/go.mod @@ -33,13 +33,13 @@ require ( github.com/imroc/req/v3 v3.13.1 github.com/jinzhu/copier v0.3.5 github.com/mattn/go-sqlite3 v2.0.3+incompatible - github.com/mattn/go-zglob v0.0.3 github.com/mitchellh/go-ps v1.0.0 github.com/mssola/user_agent v0.5.3 github.com/panjf2000/ants/v2 v2.5.0 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/qiniu/go-sdk/v7 v7.13.0 github.com/radovskyb/watcher v1.0.7 + github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 github.com/siyuan-note/dejavu v0.0.0-20220626025117-e5db5c782cbb github.com/siyuan-note/encryption v0.0.0-20220612074546-f1dd94fe8676 github.com/siyuan-note/eventbus v0.0.0-20220624162334-ca7c06dc771f @@ -93,7 +93,6 @@ require ( github.com/pelletier/go-toml/v2 v2.0.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/restic/chunker v0.4.0 // indirect - github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/ugorji/go/codec v1.2.7 // indirect diff --git a/kernel/go.sum b/kernel/go.sum index 899b5363f..cdef90d50 100644 --- a/kernel/go.sum +++ b/kernel/go.sum @@ -345,8 +345,6 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= -github.com/mattn/go-zglob v0.0.3 h1:6Ry4EYsScDyt5di4OI6xw1bYhOqfE5S33Z1OPy+d+To= -github.com/mattn/go-zglob v0.0.3/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= @@ -423,8 +421,6 @@ github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/siyuan-note/dejavu v0.0.0-20220626024131-25831e573009 h1:w2GvjKF1xFn+Swo+e+eOL9l/KQ8FvtJbwshsBInuPKg= -github.com/siyuan-note/dejavu v0.0.0-20220626024131-25831e573009/go.mod h1:i7dnOgHM41EA7xIX2CYSxYe0WhksGZidQQsLvWryK7w= github.com/siyuan-note/dejavu v0.0.0-20220626025117-e5db5c782cbb h1:7HmFGziI6a8JctJ9ouuZ4fHSsFH1GXhGfoN5pxIc2Ds= github.com/siyuan-note/dejavu v0.0.0-20220626025117-e5db5c782cbb/go.mod h1:i7dnOgHM41EA7xIX2CYSxYe0WhksGZidQQsLvWryK7w= github.com/siyuan-note/encryption v0.0.0-20220612074546-f1dd94fe8676 h1:QB9TjJQFhXhZ6dAtPpY02DlzHAQm1C+WqZq6OadG8mI= diff --git a/kernel/model/import.go b/kernel/model/import.go index e08dc59a4..f5aabfae6 100644 --- a/kernel/model/import.go +++ b/kernel/model/import.go @@ -38,7 +38,6 @@ import ( "github.com/88250/lute/html" "github.com/88250/lute/parse" "github.com/88250/protyle" - "github.com/mattn/go-zglob" "github.com/siyuan-note/filelock" "github.com/siyuan-note/siyuan/kernel/filesys" "github.com/siyuan-note/siyuan/kernel/sql" @@ -234,21 +233,22 @@ func ImportSY(zipPath, boxID, toPath string) (err error) { } } - assetsDirs, err := zglob.Glob(unzipRootPath + "/**/assets") - if nil != err { - return - } - if 0 < len(assetsDirs) { - for _, assets := range assetsDirs { - if gulu.File.IsDir(assets) { - dataAssets := filepath.Join(util.DataDir, "assets") - if err = gulu.File.Copy(assets, dataAssets); nil != err { - util.LogErrorf("copy assets from [%s] to [%s] failed: %s", assets, dataAssets, err) - return - } - } - os.RemoveAll(assets) + var assetsDirs []string + filepath.Walk(unzipRootPath, func(path string, info fs.FileInfo, err error) error { + if strings.Contains(path, "assets") && info.IsDir() { + assetsDirs = append(assetsDirs, path) } + return nil + }) + for _, assets := range assetsDirs { + if gulu.File.IsDir(assets) { + dataAssets := filepath.Join(util.DataDir, "assets") + if err = gulu.File.Copy(assets, dataAssets); nil != err { + util.LogErrorf("copy assets from [%s] to [%s] failed: %s", assets, dataAssets, err) + return + } + } + os.RemoveAll(assets) } writingDataLock.Lock() diff --git a/kernel/util/ignore.go b/kernel/util/ignore.go deleted file mode 100644 index 942d4d646..000000000 --- a/kernel/util/ignore.go +++ /dev/null @@ -1,204 +0,0 @@ -// SiYuan - Build Your Eternal Digital Garden -// Copyright (c) 2020-present, b3log.org -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package util - -// 该文件代码来自 https://github.com/go-git/go-git 项目,Apache-2.0 license - -import ( - "path/filepath" - "strings" -) - -// https://github.com/go-git/go-git/blob/master/plumbing/format/gitignore/matcher.go - -// Matcher defines a global multi-pattern matcher for gitignore patterns -type Matcher interface { - // Match matches patterns in the order of priorities. As soon as an inclusion or - // exclusion is found, not further matching is performed. - Match(path []string, isDir bool) bool -} - -// NewMatcher constructs a new global matcher. Patterns must be given in the order of -// increasing priority. That is most generic settings files first, then the content of -// the repo .gitignore, then content of .gitignore down the path or the repo and then -// the content command line arguments. -func NewMatcher(ps []Pattern) Matcher { - return &matcher{ps} -} - -type matcher struct { - patterns []Pattern -} - -func (m *matcher) Match(path []string, isDir bool) bool { - n := len(m.patterns) - for i := n - 1; i >= 0; i-- { - if match := m.patterns[i].Match(path, isDir); match > NoMatch { - return match == Exclude - } - } - return false -} - -// https://github.com/go-git/go-git/blob/master/plumbing/format/gitignore/pattern.go - -// MatchResult defines outcomes of a match, no match, exclusion or inclusion. -type MatchResult int - -const ( - // NoMatch defines the no match outcome of a match check - NoMatch MatchResult = iota - // Exclude defines an exclusion of a file as a result of a match check - Exclude - // Include defines an explicit inclusion of a file as a result of a match check - Include -) - -const ( - inclusionPrefix = "!" - zeroToManyDirs = "**" - patternDirSep = "/" -) - -// Pattern defines a single gitignore pattern. -type Pattern interface { - // Match matches the given path to the pattern. - Match(path []string, isDir bool) MatchResult -} - -type pattern struct { - domain []string - pattern []string - inclusion bool - dirOnly bool - isGlob bool -} - -// ParsePattern parses a gitignore pattern string into the Pattern structure. -func ParsePattern(p string, domain []string) Pattern { - res := pattern{domain: domain} - - if strings.HasPrefix(p, inclusionPrefix) { - res.inclusion = true - p = p[1:] - } - - if !strings.HasSuffix(p, "\\ ") { - p = strings.TrimRight(p, " ") - } - - if strings.HasSuffix(p, patternDirSep) { - res.dirOnly = true - p = p[:len(p)-1] - } - - if strings.Contains(p, patternDirSep) { - res.isGlob = true - } - - res.pattern = strings.Split(p, patternDirSep) - return &res -} - -func (p *pattern) Match(path []string, isDir bool) MatchResult { - if len(path) <= len(p.domain) { - return NoMatch - } - for i, e := range p.domain { - if path[i] != e { - return NoMatch - } - } - - path = path[len(p.domain):] - if p.isGlob && !p.globMatch(path, isDir) { - return NoMatch - } else if !p.isGlob && !p.simpleNameMatch(path, isDir) { - return NoMatch - } - - if p.inclusion { - return Include - } else { - return Exclude - } -} - -func (p *pattern) simpleNameMatch(path []string, isDir bool) bool { - for i, name := range path { - if match, err := filepath.Match(p.pattern[0], name); err != nil { - return false - } else if !match { - continue - } - if p.dirOnly && !isDir && i == len(path)-1 { - return false - } - return true - } - return false -} - -func (p *pattern) globMatch(path []string, isDir bool) bool { - matched := false - canTraverse := false - for i, pattern := range p.pattern { - if pattern == "" { - canTraverse = false - continue - } - if pattern == zeroToManyDirs { - if i == len(p.pattern)-1 { - break - } - canTraverse = true - continue - } - if strings.Contains(pattern, zeroToManyDirs) { - return false - } - if len(path) == 0 { - return false - } - if canTraverse { - canTraverse = false - for len(path) > 0 { - e := path[0] - path = path[1:] - if match, err := filepath.Match(pattern, e); err != nil { - return false - } else if match { - matched = true - break - } else if len(path) == 0 { - // if nothing left then fail - matched = false - } - } - } else { - if match, err := filepath.Match(pattern, path[0]); err != nil || !match { - return false - } - matched = true - path = path[1:] - } - } - if matched && p.dirOnly && !isDir && len(path) == 0 { - matched = false - } - return matched -} From 70104e126abdaf67f01c45aa4e17e2d4387d9554 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Mon, 27 Jun 2022 11:25:01 +0800 Subject: [PATCH 3/4] =?UTF-8?q?:art:=20=E5=90=8C=E6=AD=A5=E5=BF=BD?= =?UTF-8?q?=E7=95=A5=E6=96=87=E4=BB=B6=E9=85=8D=E7=BD=AE=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=20gitignore=20=E8=A7=84=E5=88=99=20https://github.com/siyuan-n?= =?UTF-8?q?ote/siyuan/issues/5295?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20210808180117-6v0mkxr/.siyuan/sort.json | 4 +- .../20201121224345-rc27qvo.sy | 144 +++++++++--------- .../20210808180117-czj9bvb/.siyuan/sort.json | 4 +- .../20201121212605-9td1a62.sy | 144 +++++++++--------- .../20211226090932-5lcq56f/.siyuan/sort.json | 5 + .../20211226114929-08ap1r0.sy | 144 +++++++++--------- 6 files changed, 225 insertions(+), 220 deletions(-) diff --git a/app/guide/20210808180117-6v0mkxr/.siyuan/sort.json b/app/guide/20210808180117-6v0mkxr/.siyuan/sort.json index ee00a9d15..189ae6f0b 100644 --- a/app/guide/20210808180117-6v0mkxr/.siyuan/sort.json +++ b/app/guide/20210808180117-6v0mkxr/.siyuan/sort.json @@ -1,6 +1,6 @@ { "20200923234011-ieuun1p": 1, - "20200923234602-gy54e67": 5, + "20200923234602-gy54e67": 4, "20200923234731-h3zkwm2": 2, "20200924095938-a9p5450": 2, "20200924100110-vcg96wy": 1, @@ -16,7 +16,7 @@ "20200924101256-f8b1sbi": 3, "20201004194026-s8h2cog": 15, "20201117112518-dott91x": 6, - "20201121224345-rc27qvo": 4, + "20201121224345-rc27qvo": 5, "20201204184532-3qm9l8n": 8, "20201210233038-3xr19g5": 5, "20201222100222-q47d64s": 2, diff --git a/app/guide/20210808180117-6v0mkxr/20201121224345-rc27qvo.sy b/app/guide/20210808180117-6v0mkxr/20201121224345-rc27qvo.sy index ef581f105..a55d127fb 100644 --- a/app/guide/20210808180117-6v0mkxr/20201121224345-rc27qvo.sy +++ b/app/guide/20210808180117-6v0mkxr/20201121224345-rc27qvo.sy @@ -6,7 +6,7 @@ "id": "20201121224345-rc27qvo", "title": "Acknowledgements", "type": "doc", - "updated": "20220623012804" + "updated": "20220627111416" }, "Children": [ { @@ -29,7 +29,7 @@ "ListData": {}, "Properties": { "id": "20220522101213-z3hokh2", - "updated": "20220623012804" + "updated": "20220627111416" }, "Children": [ { @@ -2132,76 +2132,6 @@ } ] }, - { - "ID": "20220522101213-yyqqx6t", - "Type": "NodeListItem", - "ListData": { - "BulletChar": 42, - "Marker": "Kg==" - }, - "Properties": { - "id": "20220522101213-yyqqx6t", - "updated": "20220522101213" - }, - "Children": [ - { - "ID": "20220522101213-1v7s6i8", - "Type": "NodeParagraph", - "Properties": { - "id": "20220522101213-1v7s6i8", - "updated": "20220522101213" - }, - "Children": [ - { - "Type": "NodeLink", - "Data": "span", - "Children": [ - { - "Type": "NodeOpenBracket" - }, - { - "Type": "NodeLinkText", - "Data": "https://github.com/mattn/go-zglob" - }, - { - "Type": "NodeCloseBracket" - }, - { - "Type": "NodeOpenParen" - }, - { - "Type": "NodeLinkDest", - "Data": "https://github.com/mattn/go-zglob" - }, - { - "Type": "NodeCloseParen" - } - ] - }, - { - "Type": "NodeText", - "Data": " " - }, - { - "Type": "NodeCodeSpan", - "Data": "code", - "Children": [ - { - "Type": "NodeCodeSpanOpenMarker" - }, - { - "Type": "NodeCodeSpanContent", - "Data": "MIT License" - }, - { - "Type": "NodeCodeSpanCloseMarker" - } - ] - } - ] - } - ] - }, { "ID": "20220522101213-s0qn0r1", "Type": "NodeListItem", @@ -2552,6 +2482,76 @@ } ] }, + { + "ID": "20220627111415-46q353e", + "Type": "NodeListItem", + "ListData": { + "BulletChar": 42, + "Marker": "Kg==" + }, + "Properties": { + "id": "20220627111415-46q353e", + "updated": "20220627111416" + }, + "Children": [ + { + "ID": "20220627111415-5kxfvm8", + "Type": "NodeParagraph", + "Properties": { + "id": "20220627111415-5kxfvm8", + "updated": "20220627111416" + }, + "Children": [ + { + "Type": "NodeLink", + "Data": "span", + "Children": [ + { + "Type": "NodeOpenBracket" + }, + { + "Type": "NodeLinkText", + "Data": "https://github.com/sabhiram/go-gitignore" + }, + { + "Type": "NodeCloseBracket" + }, + { + "Type": "NodeOpenParen" + }, + { + "Type": "NodeLinkDest", + "Data": "https://github.com/sabhiram/go-gitignore" + }, + { + "Type": "NodeCloseParen" + } + ] + }, + { + "Type": "NodeText", + "Data": " " + }, + { + "Type": "NodeCodeSpan", + "Data": "code", + "Children": [ + { + "Type": "NodeCodeSpanOpenMarker" + }, + { + "Type": "NodeCodeSpanContent", + "Data": "MIT License" + }, + { + "Type": "NodeCodeSpanCloseMarker" + } + ] + } + ] + } + ] + }, { "ID": "20220615154952-7rst1oe", "Type": "NodeListItem", diff --git a/app/guide/20210808180117-czj9bvb/.siyuan/sort.json b/app/guide/20210808180117-czj9bvb/.siyuan/sort.json index 1eea98291..659382cb3 100644 --- a/app/guide/20210808180117-czj9bvb/.siyuan/sort.json +++ b/app/guide/20210808180117-czj9bvb/.siyuan/sort.json @@ -6,7 +6,7 @@ "20200813093015-u6bopdt": 2, "20200813125307-pxsjela": 1, "20200813131152-0wk5akh": 4, - "20200813163359-v04n73b": 5, + "20200813163359-v04n73b": 4, "20200822191536-rm6hwid": 3, "20200828105441-r76vmu5": 17, "20200905090211-2vixtlf": 2, @@ -16,7 +16,7 @@ "20201002090451-hb9j8ai": 4, "20201004184819-nj8ibyg": 15, "20201117101902-2ewjjum": 6, - "20201121212605-9td1a62": 4, + "20201121212605-9td1a62": 5, "20201204181006-7bkppue": 8, "20201210103036-1x3vm8t": 5, "20201222093044-rx4zjoy": 1, diff --git a/app/guide/20210808180117-czj9bvb/20201121212605-9td1a62.sy b/app/guide/20210808180117-czj9bvb/20201121212605-9td1a62.sy index 94ca11e90..15155e3fe 100644 --- a/app/guide/20210808180117-czj9bvb/20201121212605-9td1a62.sy +++ b/app/guide/20210808180117-czj9bvb/20201121212605-9td1a62.sy @@ -6,7 +6,7 @@ "id": "20201121212605-9td1a62", "title": "致谢", "type": "doc", - "updated": "20220623012801" + "updated": "20220627111458" }, "Children": [ { @@ -29,7 +29,7 @@ "ListData": {}, "Properties": { "id": "20220522101224-ctmcj3d", - "updated": "20220623012801" + "updated": "20220627111458" }, "Children": [ { @@ -2132,76 +2132,6 @@ } ] }, - { - "ID": "20220522101224-q20v5k9", - "Type": "NodeListItem", - "ListData": { - "BulletChar": 42, - "Marker": "Kg==" - }, - "Properties": { - "id": "20220522101224-q20v5k9", - "updated": "20220522101224" - }, - "Children": [ - { - "ID": "20220522101224-9rb8tjn", - "Type": "NodeParagraph", - "Properties": { - "id": "20220522101224-9rb8tjn", - "updated": "20220522101224" - }, - "Children": [ - { - "Type": "NodeLink", - "Data": "span", - "Children": [ - { - "Type": "NodeOpenBracket" - }, - { - "Type": "NodeLinkText", - "Data": "https://github.com/mattn/go-zglob" - }, - { - "Type": "NodeCloseBracket" - }, - { - "Type": "NodeOpenParen" - }, - { - "Type": "NodeLinkDest", - "Data": "https://github.com/mattn/go-zglob" - }, - { - "Type": "NodeCloseParen" - } - ] - }, - { - "Type": "NodeText", - "Data": " " - }, - { - "Type": "NodeCodeSpan", - "Data": "code", - "Children": [ - { - "Type": "NodeCodeSpanOpenMarker" - }, - { - "Type": "NodeCodeSpanContent", - "Data": "MIT License" - }, - { - "Type": "NodeCodeSpanCloseMarker" - } - ] - } - ] - } - ] - }, { "ID": "20220522101224-z9gf2ew", "Type": "NodeListItem", @@ -2552,6 +2482,76 @@ } ] }, + { + "ID": "20220627111458-122kj45", + "Type": "NodeListItem", + "ListData": { + "BulletChar": 42, + "Marker": "Kg==" + }, + "Properties": { + "id": "20220627111458-122kj45", + "updated": "20220627111458" + }, + "Children": [ + { + "ID": "20220627111458-teblixm", + "Type": "NodeParagraph", + "Properties": { + "id": "20220627111458-teblixm", + "updated": "20220627111458" + }, + "Children": [ + { + "Type": "NodeLink", + "Data": "span", + "Children": [ + { + "Type": "NodeOpenBracket" + }, + { + "Type": "NodeLinkText", + "Data": "https://github.com/sabhiram/go-gitignore" + }, + { + "Type": "NodeCloseBracket" + }, + { + "Type": "NodeOpenParen" + }, + { + "Type": "NodeLinkDest", + "Data": "https://github.com/sabhiram/go-gitignore" + }, + { + "Type": "NodeCloseParen" + } + ] + }, + { + "Type": "NodeText", + "Data": " " + }, + { + "Type": "NodeCodeSpan", + "Data": "code", + "Children": [ + { + "Type": "NodeCodeSpanOpenMarker" + }, + { + "Type": "NodeCodeSpanContent", + "Data": "MIT License" + }, + { + "Type": "NodeCodeSpanCloseMarker" + } + ] + } + ] + } + ] + }, { "ID": "20220615155002-pupf5ye", "Type": "NodeListItem", diff --git a/app/guide/20211226090932-5lcq56f/.siyuan/sort.json b/app/guide/20211226090932-5lcq56f/.siyuan/sort.json index fa16dff18..fa0be4276 100644 --- a/app/guide/20211226090932-5lcq56f/.siyuan/sort.json +++ b/app/guide/20211226090932-5lcq56f/.siyuan/sort.json @@ -1,4 +1,9 @@ { + "20211226114339-dk0gtpr": 4, + "20211226114929-08ap1r0": 5, + "20211226115043-afhev0g": 3, + "20211226115227-r1rty9v": 2, + "20211226115423-d5z1joq": 1, "20211226115825-mhcslw2": 1, "20211226120055-9mityht": 1, "20211226120147-ib6yy3i": 2, diff --git a/app/guide/20211226090932-5lcq56f/20211226114929-08ap1r0.sy b/app/guide/20211226090932-5lcq56f/20211226114929-08ap1r0.sy index 1e08a4d71..74c6461d6 100644 --- a/app/guide/20211226090932-5lcq56f/20211226114929-08ap1r0.sy +++ b/app/guide/20211226090932-5lcq56f/20211226114929-08ap1r0.sy @@ -5,7 +5,7 @@ "icon": "1f64f", "id": "20211226114929-08ap1r0", "title": "致謝", - "updated": "20220623012807" + "updated": "20220627111449" }, "Children": [ { @@ -28,7 +28,7 @@ "ListData": {}, "Properties": { "id": "20220326092650-r61gazd", - "updated": "20220623012807" + "updated": "20220627111449" }, "Children": [ { @@ -2131,76 +2131,6 @@ } ] }, - { - "ID": "20220326092650-9kiqzey", - "Type": "NodeListItem", - "ListData": { - "BulletChar": 42, - "Marker": "Kg==" - }, - "Properties": { - "id": "20220326092650-9kiqzey", - "updated": "20220326092650" - }, - "Children": [ - { - "ID": "20220326092650-rqswxe2", - "Type": "NodeParagraph", - "Properties": { - "id": "20220326092650-rqswxe2", - "updated": "20220326092650" - }, - "Children": [ - { - "Type": "NodeLink", - "Data": "span", - "Children": [ - { - "Type": "NodeOpenBracket" - }, - { - "Type": "NodeLinkText", - "Data": "https://github.com/mattn/go-zglob" - }, - { - "Type": "NodeCloseBracket" - }, - { - "Type": "NodeOpenParen" - }, - { - "Type": "NodeLinkDest", - "Data": "https://github.com/mattn/go-zglob" - }, - { - "Type": "NodeCloseParen" - } - ] - }, - { - "Type": "NodeText", - "Data": " " - }, - { - "Type": "NodeCodeSpan", - "Data": "code", - "Children": [ - { - "Type": "NodeCodeSpanOpenMarker" - }, - { - "Type": "NodeCodeSpanContent", - "Data": "MIT License" - }, - { - "Type": "NodeCodeSpanCloseMarker" - } - ] - } - ] - } - ] - }, { "ID": "20220326092650-13vd1m8", "Type": "NodeListItem", @@ -2551,6 +2481,76 @@ } ] }, + { + "ID": "20220627111449-fd85wp4", + "Type": "NodeListItem", + "ListData": { + "BulletChar": 42, + "Marker": "Kg==" + }, + "Properties": { + "id": "20220627111449-fd85wp4", + "updated": "20220627111449" + }, + "Children": [ + { + "ID": "20220627111449-lv7og5c", + "Type": "NodeParagraph", + "Properties": { + "id": "20220627111449-lv7og5c", + "updated": "20220627111449" + }, + "Children": [ + { + "Type": "NodeLink", + "Data": "span", + "Children": [ + { + "Type": "NodeOpenBracket" + }, + { + "Type": "NodeLinkText", + "Data": "https://github.com/sabhiram/go-gitignore" + }, + { + "Type": "NodeCloseBracket" + }, + { + "Type": "NodeOpenParen" + }, + { + "Type": "NodeLinkDest", + "Data": "https://github.com/sabhiram/go-gitignore" + }, + { + "Type": "NodeCloseParen" + } + ] + }, + { + "Type": "NodeText", + "Data": " " + }, + { + "Type": "NodeCodeSpan", + "Data": "code", + "Children": [ + { + "Type": "NodeCodeSpanOpenMarker" + }, + { + "Type": "NodeCodeSpanContent", + "Data": "MIT License" + }, + { + "Type": "NodeCodeSpanCloseMarker" + } + ] + } + ] + } + ] + }, { "ID": "20220615154944-8ye5ub9", "Type": "NodeListItem", From 0b967f4c1a197ff885ec4bce49323dfb6666aec1 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Mon, 27 Jun 2022 11:39:29 +0800 Subject: [PATCH 4/4] =?UTF-8?q?:bug:=20=E4=BD=BF=E7=94=A8=E5=9D=97?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E6=9D=A1=E8=B7=B3=E8=BD=AC=E5=88=B0=E6=9C=80?= =?UTF-8?q?=E5=90=8E=E4=B8=80=E4=B8=AA=E5=9D=97=E6=97=B6=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E4=B8=8A=E9=9D=A2=E7=9A=84=E5=9D=97=20https:?= =?UTF-8?q?//github.com/siyuan-note/siyuan/issues/5291?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/model/file.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/model/file.go b/kernel/model/file.go index cfacabc7e..c9fe820ab 100644 --- a/kernel/model/file.go +++ b/kernel/model/file.go @@ -657,7 +657,7 @@ func GetDoc(id string, index int, keyword string, mode int, size int) (blockCoun } func loadNodesByMode(node *ast.Node, inputIndex, mode, size int, isDoc, isHeading bool) (nodes []*ast.Node, eof bool) { - if 2 == mode { // 向下 + if 0 == mode /* 仅当前 */ || 2 == mode /* 向下 */ { next := node.Next if ast.NodeHeading == node.Type && "1" == node.IALAttr("fold") { // 标题展开时进行动态加载导致重复内容 https://github.com/siyuan-note/siyuan/issues/4671