New Upstream Release - golang-github-go-git-go-billy
Ready changes
Summary
Merged new upstream version: 5.4.1 (was: 5.3.1).
Resulting package
Built on 2023-02-09T06:54 (took 19m35s)
The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:
apt install -t fresh-releases golang-github-go-git-go-billy-dev
Lintian Result
Diff
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 4e9980e..3098fee 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -1,18 +1,19 @@
on: [push, pull_request]
name: Test
+permissions: {}
jobs:
test:
strategy:
matrix:
- go-version: [1.14.x, 1.15.x, 1.16.x]
+ go-version: [1.19.x,1.20.x]
platform: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.platform }}
steps:
- name: Install Go
- uses: actions/setup-go@v1
+ uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Test
- run: go test ./...
\ No newline at end of file
+ run: make test
diff --git a/.github/workflows/test_js.yml b/.github/workflows/test_js.yml
index c55e6d5..5889a44 100644
--- a/.github/workflows/test_js.yml
+++ b/.github/workflows/test_js.yml
@@ -1,24 +1,25 @@
on: [push, pull_request]
-name: Test
+name: Test JS
+permissions: {}
jobs:
test:
strategy:
matrix:
- go-version: [1.14.x, 1.15.x, 1.16.x]
+ go-version: [1.18.x,1.19.x]
runs-on: ubuntu-latest
steps:
- name: Install Go
- uses: actions/setup-go@v1
+ uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
- name: Install wasmbrowsertest
run: |
- go get github.com/agnivade/wasmbrowsertest
+ go install github.com/agnivade/wasmbrowsertest@latest
mv $HOME/go/bin/wasmbrowsertest $HOME/go/bin/go_js_wasm_exec
- name: Checkout code
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Test
run: go test -exec="$HOME/go/bin/go_js_wasm_exec" ./...
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..74dad8b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,11 @@
+# Go parameters
+GOCMD = go
+GOTEST = $(GOCMD) test
+
+.PHONY: test
+test:
+ $(GOTEST) -race ./...
+
+test-coverage:
+ echo "" > $(COVERAGE_REPORT); \
+ $(GOTEST) -coverprofile=$(COVERAGE_REPORT) -coverpkg=./... -covermode=$(COVERAGE_MODE) ./...
diff --git a/debian/changelog b/debian/changelog
index 6081e3d..d8f3293 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+golang-github-go-git-go-billy (5.4.1-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk> Thu, 09 Feb 2023 06:37:29 -0000
+
golang-github-go-git-go-billy (5.3.1-3) unstable; urgency=medium
* Source only upload for migration to testing
diff --git a/go.mod b/go.mod
index 78ce0af..6c8c200 100644
--- a/go.mod
+++ b/go.mod
@@ -3,8 +3,8 @@ module github.com/go-git/go-billy/v5
require (
github.com/kr/text v0.2.0 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
- golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527
- gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f
+ golang.org/x/sys v0.3.0
+ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
)
go 1.13
diff --git a/go.sum b/go.sum
index cdc052b..66b4216 100644
--- a/go.sum
+++ b/go.sum
@@ -1,6 +1,8 @@
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/go-git/go-billy v1.0.0 h1:bXR6Zu3opPSg0R4dDxqaLglY4rxw7ja7wS16qSpOKL4=
github.com/go-git/go-billy v3.1.0+incompatible h1:dwrJ8G2Jt1srYgIJs+lRjA36qBY68O2Lg5idKG8ef5M=
+github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
@@ -10,5 +12,11 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
+golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
diff --git a/memfs/memory.go b/memfs/memory.go
index f217693..dab7396 100644
--- a/memfs/memory.go
+++ b/memfs/memory.go
@@ -310,14 +310,14 @@ func (f *file) Duplicate(filename string, mode os.FileMode, flag int) billy.File
flag: flag,
}
- if isAppend(flag) {
- new.position = int64(new.content.Len())
- }
-
if isTruncate(flag) {
new.content.Truncate()
}
+ if isAppend(flag) {
+ new.position = int64(new.content.Len())
+ }
+
return new
}
diff --git a/memfs/memory_test.go b/memfs/memory_test.go
index b79ac2f..b23f7ae 100644
--- a/memfs/memory_test.go
+++ b/memfs/memory_test.go
@@ -8,6 +8,7 @@ import (
"github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/test"
+ "github.com/go-git/go-billy/v5/util"
. "gopkg.in/check.v1"
)
@@ -47,7 +48,6 @@ func (s *MemorySuite) TestNegativeOffsets(c *C) {
c.Assert(err, ErrorMatches, "writeat negative: negative offset")
}
-
func (s *MemorySuite) TestExclusive(c *C) {
f, err := s.FS.OpenFile("exclusive", os.O_CREATE|os.O_EXCL|os.O_RDWR, 0666)
c.Assert(err, IsNil)
@@ -74,8 +74,8 @@ func (s *MemorySuite) TestOrder(c *C) {
c.Assert(err, IsNil)
}
- attemps := 30
- for n := 0; n < attemps; n++ {
+ attempts := 30
+ for n := 0; n < attempts; n++ {
actual, err := s.FS.ReadDir("")
c.Assert(err, IsNil)
@@ -84,3 +84,22 @@ func (s *MemorySuite) TestOrder(c *C) {
}
}
}
+
+func (s *MemorySuite) TestTruncateAppend(c *C) {
+ err := util.WriteFile(s.FS, "truncate_append", []byte("file-content"), 0666)
+ c.Assert(err, IsNil)
+
+ f, err := s.FS.OpenFile("truncate_append", os.O_WRONLY|os.O_TRUNC|os.O_APPEND, 0666)
+ c.Assert(err, IsNil)
+
+ n, err := f.Write([]byte("replace"))
+ c.Assert(err, IsNil)
+ c.Assert(n, Equals, len("replace"))
+
+ err = f.Close()
+ c.Assert(err, IsNil)
+
+ data, err := util.ReadFile(s.FS, "truncate_append")
+ c.Assert(err, IsNil)
+ c.Assert(string(data), Equals, "replace")
+}
diff --git a/memfs/storage.go b/memfs/storage.go
index d3ff5a2..e3c4e38 100644
--- a/memfs/storage.go
+++ b/memfs/storage.go
@@ -6,6 +6,7 @@ import (
"io"
"os"
"path/filepath"
+ "sync"
)
type storage struct {
@@ -174,6 +175,8 @@ func clean(path string) string {
type content struct {
name string
bytes []byte
+
+ m sync.RWMutex
}
func (c *content) WriteAt(p []byte, off int64) (int, error) {
@@ -185,6 +188,7 @@ func (c *content) WriteAt(p []byte, off int64) (int, error) {
}
}
+ c.m.Lock()
prev := len(c.bytes)
diff := int(off) - prev
@@ -196,6 +200,7 @@ func (c *content) WriteAt(p []byte, off int64) (int, error) {
if len(c.bytes) < prev {
c.bytes = c.bytes[:prev]
}
+ c.m.Unlock()
return len(p), nil
}
@@ -209,8 +214,10 @@ func (c *content) ReadAt(b []byte, off int64) (n int, err error) {
}
}
+ c.m.RLock()
size := int64(len(c.bytes))
if off >= size {
+ c.m.RUnlock()
return 0, io.EOF
}
@@ -220,10 +227,12 @@ func (c *content) ReadAt(b []byte, off int64) (n int, err error) {
}
btr := c.bytes[off : off+l]
+ n = copy(b, btr)
+
if len(btr) < len(b) {
err = io.EOF
}
- n = copy(b, btr)
+ c.m.RUnlock()
return
}
diff --git a/util/walk.go b/util/walk.go
new file mode 100644
index 0000000..1531bca
--- /dev/null
+++ b/util/walk.go
@@ -0,0 +1,72 @@
+package util
+
+import (
+ "os"
+ "path/filepath"
+
+ "github.com/go-git/go-billy/v5"
+)
+
+// walk recursively descends path, calling walkFn
+// adapted from https://golang.org/src/path/filepath/path.go
+func walk(fs billy.Filesystem, path string, info os.FileInfo, walkFn filepath.WalkFunc) error {
+ if !info.IsDir() {
+ return walkFn(path, info, nil)
+ }
+
+ names, err := readdirnames(fs, path)
+ err1 := walkFn(path, info, err)
+ // If err != nil, walk can't walk into this directory.
+ // err1 != nil means walkFn want walk to skip this directory or stop walking.
+ // Therefore, if one of err and err1 isn't nil, walk will return.
+ if err != nil || err1 != nil {
+ // The caller's behavior is controlled by the return value, which is decided
+ // by walkFn. walkFn may ignore err and return nil.
+ // If walkFn returns SkipDir, it will be handled by the caller.
+ // So walk should return whatever walkFn returns.
+ return err1
+ }
+
+ for _, name := range names {
+ filename := filepath.Join(path, name)
+ fileInfo, err := fs.Lstat(filename)
+ if err != nil {
+ if err := walkFn(filename, fileInfo, err); err != nil && err != filepath.SkipDir {
+ return err
+ }
+ } else {
+ err = walk(fs, filename, fileInfo, walkFn)
+ if err != nil {
+ if !fileInfo.IsDir() || err != filepath.SkipDir {
+ return err
+ }
+ }
+ }
+ }
+ return nil
+}
+
+// Walk walks the file tree rooted at root, calling fn for each file or
+// directory in the tree, including root. All errors that arise visiting files
+// and directories are filtered by fn: see the WalkFunc documentation for
+// details.
+//
+// The files are walked in lexical order, which makes the output deterministic
+// but requires Walk to read an entire directory into memory before proceeding
+// to walk that directory. Walk does not follow symbolic links.
+//
+// Function adapted from https://github.com/golang/go/blob/3b770f2ccb1fa6fecc22ea822a19447b10b70c5c/src/path/filepath/path.go#L500
+func Walk(fs billy.Filesystem, root string, walkFn filepath.WalkFunc) error {
+ info, err := fs.Lstat(root)
+ if err != nil {
+ err = walkFn(root, nil, err)
+ } else {
+ err = walk(fs, root, info, walkFn)
+ }
+
+ if err == filepath.SkipDir {
+ return nil
+ }
+
+ return err
+}
diff --git a/util/walk_test.go b/util/walk_test.go
new file mode 100644
index 0000000..7cd80d8
--- /dev/null
+++ b/util/walk_test.go
@@ -0,0 +1,195 @@
+package util_test
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "path/filepath"
+ "reflect"
+ "testing"
+
+ "github.com/go-git/go-billy/v5"
+ "github.com/go-git/go-billy/v5/memfs"
+ "github.com/go-git/go-billy/v5/util"
+
+ . "gopkg.in/check.v1"
+)
+
+type WalkSuite struct{}
+
+func TestWalk(t *testing.T) { TestingT(t) }
+
+var _ = Suite(&WalkSuite{})
+var targetSubfolder = filepath.FromSlash("path/to/some/subfolder")
+
+func (s *WalkSuite) TestWalkCanSkipTopDirectory(c *C) {
+ filesystem := memfs.New()
+ c.Assert(util.Walk(filesystem, "/root/that/does/not/exist", func(path string, info os.FileInfo, err error) error { return filepath.SkipDir }), IsNil)
+}
+
+func (s *WalkSuite) TestWalkReturnsAnErrorWhenRootDoesNotExist(c *C) {
+ filesystem := memfs.New()
+ c.Assert(util.Walk(filesystem, "/root/that/does/not/exist", func(path string, info os.FileInfo, err error) error { return err }), NotNil)
+}
+
+func (s *WalkSuite) TestWalkOnPlainFile(c *C) {
+ filesystem := memfs.New()
+ createFile(c, filesystem, "./README.md")
+ discoveredPaths := []string{}
+ c.Assert(util.Walk(filesystem, "./README.md", func(path string, info os.FileInfo, err error) error {
+ discoveredPaths = append(discoveredPaths, path)
+ return nil
+ }), IsNil)
+ c.Assert(discoveredPaths, DeepEquals, []string{"./README.md"})
+}
+
+func (s *WalkSuite) TestWalkOnExistingFolder(c *C) {
+ filesystem := memfs.New()
+ createFile(c, filesystem, "path/to/some/subfolder/that/contain/file")
+ createFile(c, filesystem, "path/to/some/file")
+ discoveredPaths := []string{}
+ c.Assert(util.Walk(filesystem, "path", func(path string, info os.FileInfo, err error) error {
+ discoveredPaths = append(discoveredPaths, path)
+ return nil
+ }), IsNil)
+ c.Assert(discoveredPaths, Contains, "path")
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to"))
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some"))
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/file"))
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/subfolder"))
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/subfolder/that"))
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/subfolder/that/contain"))
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/subfolder/that/contain/file"))
+}
+
+func (s *WalkSuite) TestWalkCanSkipFolder(c *C) {
+ filesystem := memfs.New()
+ createFile(c, filesystem, "path/to/some/subfolder/that/contain/file")
+ createFile(c, filesystem, "path/to/some/file")
+ discoveredPaths := []string{}
+ c.Assert(util.Walk(filesystem, "path", func(path string, info os.FileInfo, err error) error {
+ discoveredPaths = append(discoveredPaths, path)
+ if path == targetSubfolder {
+ return filepath.SkipDir
+ }
+ return nil
+ }), IsNil)
+ c.Assert(discoveredPaths, Contains, "path")
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to"))
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some"))
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/file"))
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/subfolder"))
+ c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that"))
+ c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that/contain"))
+ c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that/contain/file"))
+}
+
+func (s *WalkSuite) TestWalkStopsOnError(c *C) {
+ filesystem := memfs.New()
+ createFile(c, filesystem, "path/to/some/subfolder/that/contain/file")
+ createFile(c, filesystem, "path/to/some/file")
+ discoveredPaths := []string{}
+ c.Assert(util.Walk(filesystem, "path", func(path string, info os.FileInfo, err error) error {
+ discoveredPaths = append(discoveredPaths, path)
+ if path == targetSubfolder {
+ return errors.New("uncaught error")
+ }
+ return nil
+ }), NotNil)
+ c.Assert(discoveredPaths, Contains, "path")
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to"))
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some"))
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/file"))
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/subfolder"))
+ c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that"))
+ c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that/contain"))
+ c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that/contain/file"))
+}
+
+func (s *WalkSuite) TestWalkForwardsStatErrors(c *C) {
+ memFilesystem := memfs.New()
+ filesystem := &fnFs{
+ Filesystem: memFilesystem,
+ lstat: func(path string) (os.FileInfo, error) {
+ if path == targetSubfolder {
+ return nil, errors.New("uncaught error")
+ }
+ return memFilesystem.Lstat(path)
+ },
+ }
+
+ createFile(c, filesystem, "path/to/some/subfolder/that/contain/file")
+ createFile(c, filesystem, "path/to/some/file")
+ discoveredPaths := []string{}
+ c.Assert(util.Walk(filesystem, "path", func(path string, info os.FileInfo, err error) error {
+ discoveredPaths = append(discoveredPaths, path)
+ if path == targetSubfolder {
+ c.Assert(err, NotNil)
+ }
+ return err
+ }), NotNil)
+ c.Assert(discoveredPaths, Contains, "path")
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to"))
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some"))
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/file"))
+ c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/subfolder"))
+ c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that"))
+ c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that/contain"))
+ c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that/contain/file"))
+}
+
+func createFile(c *C, filesystem billy.Filesystem, path string) {
+ fd, err := filesystem.Create(path)
+ c.Assert(err, IsNil)
+ if err != nil {
+ fd.Close()
+ }
+}
+
+type fnFs struct {
+ billy.Filesystem
+ lstat func(path string) (os.FileInfo, error)
+}
+
+func (f *fnFs) Lstat(path string) (os.FileInfo, error) {
+ if f.lstat != nil {
+ return f.lstat(path)
+ }
+ return nil, errors.New("not implemented")
+}
+
+type containsChecker struct {
+ *CheckerInfo
+}
+
+func (checker *containsChecker) Check(params []interface{}, names []string) (result bool, err string) {
+ defer func() {
+ if v := recover(); v != nil {
+ result = false
+ err = fmt.Sprint(v)
+ }
+ }()
+
+ value := reflect.ValueOf(params[0])
+ result = false
+ err = fmt.Sprintf("%v does not contain %v", params[0], params[1])
+ switch value.Kind() {
+ case reflect.Array, reflect.Slice:
+ for i := 0; i < value.Len(); i++ {
+ r := reflect.DeepEqual(value.Index(i).Interface(), params[1])
+ if r {
+ result = true
+ err = ""
+ }
+ }
+ default:
+ return false, "obtained value type is not iterable"
+ }
+ return
+}
+
+var Contains Checker = &containsChecker{
+ &CheckerInfo{Name: "Contains", Params: []string{"obtained", "expected"}},
+}
+
+var NotContain Checker = Not(Contains)
Debdiff
[The following lists of changes regard files as different if they have different names, permissions or owners.]
Files in second set of .debs but not in first
-rw-r--r-- root/root /usr/share/gocode/src/github.com/go-git/go-billy/v5/util/walk.go -rw-r--r-- root/root /usr/share/gocode/src/github.com/go-git/go-billy/v5/util/walk_test.go
No differences were encountered in the control files