New Upstream Snapshot - golang-github-cznic-fileutil

Ready changes

Summary

Merged new upstream version: 1.1.2 (was: 0.0~git20200808.2079183).

Diff

diff --git a/Makefile b/Makefile
index 1319b03..68fcb0c 100644
--- a/Makefile
+++ b/Makefile
@@ -2,33 +2,37 @@
 # Use of this source code is governed by a BSD-style
 # license that can be found in the LICENSE file.
 
-.PHONY: all clean editor build_all todo
+.PHONY: all clean edit editor build_all_targets todo
 
 all: editor
-	go vet
-	golint .
-	go install
-	make todo
 
-editor:
-	go fmt
-	go test -i
-	go test
-	go build
+build_all_targets:
+	GOOS=darwin GOARCH=amd64 go build -v ./...
+	GOOS=darwin GOARCH=arm64 go build -v ./...
+	GOOS=freebsd GOARCH=386 go build -v ./...
+	GOOS=freebsd GOARCH=amd64 go build -v ./...
+	GOOS=linux GOARCH=386 go build -v ./...
+	GOOS=linux GOARCH=amd64 go build -v ./...
+	GOOS=linux GOARCH=arm go build -v ./...
+	GOOS=linux GOARCH=arm64 go build -v ./...
+	GOOS=linux GOARCH=ppc64le go build -v ./...
+	GOOS=linux GOARCH=riscv64 go build -v ./...
+	GOOS=linux GOARCH=s390x go build -v ./...
+	GOOS=netbsd GOARCH=amd64 go build -v ./...
+	GOOS=openbsd GOARCH=amd64 go build -v ./...
+	GOOS=openbsd GOARCH=amd64 go build -v ./...
+	GOOS=windows GOARCH=386 go build -v ./...
+	GOOS=windows GOARCH=amd64 go build -v ./...
 
-PLATFORMS=darwin dragonfly freebsd linux netbsd openbsd plan9 solaris windows
-ARCHITECTURES=386 amd64 arm arm64
-
-build_all:
-	$(foreach GOOS, $(PLATFORMS),\
-	$(foreach GOARCH, $(ARCHITECTURES), $(shell export GOOS=$(GOOS); export GOARCH=$(GOARCH); go build -v -o /dev/null || go env)))
+clean:
+	rm -f log-* cpu.test mem.test *.out
+	go clean
 
-todo:
-	@grep -n ^[[:space:]]*_[[:space:]]*=[[:space:]][[:alpha:]][[:alnum:]]* *.go || true
-	@grep -n TODO *.go || true
-	@grep -n BUG *.go || true
-	@grep -n println *.go || true
+edit:
+	@touch log
+	@if [ -f "Session.vim" ]; then gvim -S & else gvim -p Makefile *.go & fi
 
-clean:
-	@go clean
-	rm -f y.output
+editor:
+	gofmt -l -s -w .
+	go test
+	go build
diff --git a/debian/changelog b/debian/changelog
index e1b5544..ecdf191 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+golang-github-cznic-fileutil (1.1.2-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Wed, 08 Feb 2023 19:11:57 -0000
+
 golang-github-cznic-fileutil (0.0~git20200808.2079183-4) unstable; urgency=medium
 
   * Team upload.
diff --git a/debian/patches/mathutil-old-import.patch b/debian/patches/mathutil-old-import.patch
index 53b9352..72e0986 100644
--- a/debian/patches/mathutil-old-import.patch
+++ b/debian/patches/mathutil-old-import.patch
@@ -1,5 +1,7 @@
---- a/falloc/all_test.go
-+++ b/falloc/all_test.go
+Index: golang-github-cznic-fileutil.git/falloc/all_test.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/falloc/all_test.go
++++ golang-github-cznic-fileutil.git/falloc/all_test.go
 @@ -4,7 +4,7 @@
  
  // blame: jnml, labs.nic.cz
@@ -9,7 +11,7 @@
  
  import (
  	"bytes"
-@@ -22,7 +22,7 @@
+@@ -22,7 +22,7 @@ import (
  
  	"modernc.org/fileutil"
  	"modernc.org/fileutil/storage"
@@ -18,8 +20,10 @@
  )
  
  var (
---- a/falloc/test_deps.go
-+++ b/falloc/test_deps.go
+Index: golang-github-cznic-fileutil.git/falloc/test_deps.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/falloc/test_deps.go
++++ golang-github-cznic-fileutil.git/falloc/test_deps.go
 @@ -4,12 +4,12 @@
  
  // blame: jnml, labs.nic.cz
@@ -35,8 +39,10 @@
 -	_ "modernc.org/mathutil"
 +	_ "github.com/cznic/mathutil"
  )
---- a/all_test.go
-+++ b/all_test.go
+Index: golang-github-cznic-fileutil.git/all_test.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/all_test.go
++++ golang-github-cznic-fileutil.git/all_test.go
 @@ -2,7 +2,7 @@
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
@@ -46,9 +52,11 @@
  
  import (
  	"os"
---- a/fileutil_allarms.go
-+++ b/fileutil_allarms.go
-@@ -7,7 +7,7 @@
+Index: golang-github-cznic-fileutil.git/fileutil_allarms.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/fileutil_allarms.go
++++ golang-github-cznic-fileutil.git/fileutil_allarms.go
+@@ -8,7 +8,7 @@
  // +build !openbsd
  // +build !plan9
  
@@ -57,63 +65,75 @@
  
  import (
  	"io"
---- a/fileutil_darwin.go
-+++ b/fileutil_darwin.go
+Index: golang-github-cznic-fileutil.git/fileutil_darwin.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/fileutil_darwin.go
++++ golang-github-cznic-fileutil.git/fileutil_darwin.go
 @@ -5,7 +5,7 @@
- // +build !arm
- // +build !arm64
+ //go:build !arm && !arm64
+ // +build !arm,!arm64
  
 -package fileutil // import "modernc.org/fileutil"
 +package fileutil
  
  import (
  	"io"
---- a/fileutil_dragonfly.go
-+++ b/fileutil_dragonfly.go
+Index: golang-github-cznic-fileutil.git/fileutil_dragonfly.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/fileutil_dragonfly.go
++++ golang-github-cznic-fileutil.git/fileutil_dragonfly.go
 @@ -5,7 +5,7 @@
- // +build !arm
- // +build !arm64
+ //go:build !arm && !arm64
+ // +build !arm,!arm64
  
 -package fileutil // import "modernc.org/fileutil"
 +package fileutil
  
  import (
  	"io"
---- a/fileutil_freebsd.go
-+++ b/fileutil_freebsd.go
+Index: golang-github-cznic-fileutil.git/fileutil_freebsd.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/fileutil_freebsd.go
++++ golang-github-cznic-fileutil.git/fileutil_freebsd.go
 @@ -5,7 +5,7 @@
- // +build !arm
- // +build !arm64
+ //go:build !arm && !arm64
+ // +build !arm,!arm64
  
 -package fileutil // import "modernc.org/fileutil"
 +package fileutil
  
  import (
  	"io"
---- a/fileutil_linux.go
-+++ b/fileutil_linux.go
+Index: golang-github-cznic-fileutil.git/fileutil_linux.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/fileutil_linux.go
++++ golang-github-cznic-fileutil.git/fileutil_linux.go
 @@ -5,7 +5,7 @@
- // +build !arm
- // +build !arm64
+ //go:build !arm && !arm64
+ // +build !arm,!arm64
  
 -package fileutil // import "modernc.org/fileutil"
 +package fileutil
  
  import (
  	"bytes"
---- a/fileutil_netbsd.go
-+++ b/fileutil_netbsd.go
+Index: golang-github-cznic-fileutil.git/fileutil_netbsd.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/fileutil_netbsd.go
++++ golang-github-cznic-fileutil.git/fileutil_netbsd.go
 @@ -5,7 +5,7 @@
- // +build !arm
- // +build !arm64
+ //go:build !arm && !arm64
+ // +build !arm,!arm64
  
 -package fileutil // import "modernc.org/fileutil"
 +package fileutil
  
  import (
  	"io"
---- a/fileutil_openbsd.go
-+++ b/fileutil_openbsd.go
+Index: golang-github-cznic-fileutil.git/fileutil_openbsd.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/fileutil_openbsd.go
++++ golang-github-cznic-fileutil.git/fileutil_openbsd.go
 @@ -2,7 +2,7 @@
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
@@ -123,8 +143,10 @@
  
  import (
  	"io"
---- a/fileutil_plan9.go
-+++ b/fileutil_plan9.go
+Index: golang-github-cznic-fileutil.git/fileutil_plan9.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/fileutil_plan9.go
++++ golang-github-cznic-fileutil.git/fileutil_plan9.go
 @@ -2,7 +2,7 @@
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
@@ -134,10 +156,12 @@
  
  import (
  	"io"
---- a/fileutil_solaris.go
-+++ b/fileutil_solaris.go
-@@ -4,7 +4,7 @@
- 
+Index: golang-github-cznic-fileutil.git/fileutil_solaris.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/fileutil_solaris.go
++++ golang-github-cznic-fileutil.git/fileutil_solaris.go
+@@ -5,7 +5,7 @@
+ //go:build go1.3
  // +build go1.3
  
 -package fileutil // import "modernc.org/fileutil"
@@ -145,8 +169,10 @@
  
  import (
  	"io"
---- a/fileutil_windows.go
-+++ b/fileutil_windows.go
+Index: golang-github-cznic-fileutil.git/fileutil_windows.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/fileutil_windows.go
++++ golang-github-cznic-fileutil.git/fileutil_windows.go
 @@ -2,7 +2,7 @@
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
@@ -156,10 +182,12 @@
  
  import (
  	"io"
---- a/punch_test.go
-+++ b/punch_test.go
-@@ -4,7 +4,7 @@
- 
+Index: golang-github-cznic-fileutil.git/punch_test.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/punch_test.go
++++ golang-github-cznic-fileutil.git/punch_test.go
+@@ -5,7 +5,7 @@
+ //go:build amd64 || amd64p32 || arm64 || arm64be || ppc64 || ppc64le || mips64 || mips64le || mips64p32 || mips64p32le || sparc64
  // +build amd64 amd64p32 arm64 arm64be ppc64 ppc64le mips64 mips64le mips64p32 mips64p32le sparc64
  
 -package fileutil // import "modernc.org/fileutil"
@@ -167,8 +195,10 @@
  
  import (
  	"io/ioutil"
---- a/test_deps.go
-+++ b/test_deps.go
+Index: golang-github-cznic-fileutil.git/test_deps.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/test_deps.go
++++ golang-github-cznic-fileutil.git/test_deps.go
 @@ -4,7 +4,7 @@
  
  // blame: jnml, labs.nic.cz
@@ -178,9 +208,11 @@
  
  // Pull test dependencies too.
  // Enables easy 'go test X' after 'go get X'
---- a/falloc/docs.go
-+++ b/falloc/docs.go
-@@ -244,7 +244,7 @@
+Index: golang-github-cznic-fileutil.git/falloc/docs.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/falloc/docs.go
++++ golang-github-cznic-fileutil.git/falloc/docs.go
+@@ -244,7 +244,7 @@ FLTT describes the type of the Free List
  FLTT == 0: Free List Table is fixed at atom address 2. It has a fixed size for 3856 entries
  for free list of size 1..3855 atoms and the last is for the list of free block >= 3856 atoms.
  */
@@ -189,8 +221,10 @@
  
  const (
  	INVALID_HANDLE = Handle(-1)
---- a/falloc/error.go
-+++ b/falloc/error.go
+Index: golang-github-cznic-fileutil.git/falloc/error.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/falloc/error.go
++++ golang-github-cznic-fileutil.git/falloc/error.go
 @@ -4,7 +4,7 @@
  
  // blame: jnml, labs.nic.cz
@@ -200,8 +234,10 @@
  
  import "fmt"
  
---- a/hdb/all_test.go
-+++ b/hdb/all_test.go
+Index: golang-github-cznic-fileutil.git/hdb/all_test.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/hdb/all_test.go
++++ golang-github-cznic-fileutil.git/hdb/all_test.go
 @@ -4,7 +4,7 @@
  
  // blame: jnml, labs.nic.cz
@@ -211,8 +247,10 @@
  
  import (
  	"testing"
---- a/hdb/test_deps.go
-+++ b/hdb/test_deps.go
+Index: golang-github-cznic-fileutil.git/hdb/test_deps.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/hdb/test_deps.go
++++ golang-github-cznic-fileutil.git/hdb/test_deps.go
 @@ -4,7 +4,7 @@
  
  // blame: jnml, labs.nic.cz
@@ -222,8 +260,10 @@
  
  // Pull test dependencies too.
  // Enables easy 'go test X' after 'go get X'
---- a/storage/all_test.go
-+++ b/storage/all_test.go
+Index: golang-github-cznic-fileutil.git/storage/all_test.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/storage/all_test.go
++++ golang-github-cznic-fileutil.git/storage/all_test.go
 @@ -4,7 +4,7 @@
  
  // blame: jnml, labs.nic.cz
@@ -233,8 +273,10 @@
  
  import (
  	"flag"
---- a/storage/cache.go
-+++ b/storage/cache.go
+Index: golang-github-cznic-fileutil.git/storage/cache.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/storage/cache.go
++++ golang-github-cznic-fileutil.git/storage/cache.go
 @@ -4,7 +4,7 @@
  
  // blame: jnml, labs.nic.cz
@@ -244,8 +286,10 @@
  
  import (
  	"container/list"
---- a/storage/cache_test.go
-+++ b/storage/cache_test.go
+Index: golang-github-cznic-fileutil.git/storage/cache_test.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/storage/cache_test.go
++++ golang-github-cznic-fileutil.git/storage/cache_test.go
 @@ -4,7 +4,7 @@
  
  // blame: jnml, labs.nic.cz
@@ -255,8 +299,10 @@
  
  import (
  	"io/ioutil"
---- a/storage/dev_test.go
-+++ b/storage/dev_test.go
+Index: golang-github-cznic-fileutil.git/storage/dev_test.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/storage/dev_test.go
++++ golang-github-cznic-fileutil.git/storage/dev_test.go
 @@ -4,7 +4,7 @@
  
  // blame: jnml, labs.nic.cz
@@ -266,8 +312,10 @@
  
  import (
  	"testing"
---- a/storage/file.go
-+++ b/storage/file.go
+Index: golang-github-cznic-fileutil.git/storage/file.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/storage/file.go
++++ golang-github-cznic-fileutil.git/storage/file.go
 @@ -4,7 +4,7 @@
  
  // blame: jnml, labs.nic.cz
@@ -277,8 +325,10 @@
  
  import (
  	"os"
---- a/storage/mem.go
-+++ b/storage/mem.go
+Index: golang-github-cznic-fileutil.git/storage/mem.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/storage/mem.go
++++ golang-github-cznic-fileutil.git/storage/mem.go
 @@ -4,7 +4,7 @@
  
  // blame: jnml, labs.nic.cz
@@ -288,8 +338,10 @@
  
  import (
  	"errors"
---- a/storage/mem_test.go
-+++ b/storage/mem_test.go
+Index: golang-github-cznic-fileutil.git/storage/mem_test.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/storage/mem_test.go
++++ golang-github-cznic-fileutil.git/storage/mem_test.go
 @@ -4,7 +4,7 @@
  
  // blame: jnml, labs.nic.cz
@@ -299,8 +351,10 @@
  
  import (
  	"testing"
---- a/storage/probe.go
-+++ b/storage/probe.go
+Index: golang-github-cznic-fileutil.git/storage/probe.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/storage/probe.go
++++ golang-github-cznic-fileutil.git/storage/probe.go
 @@ -4,7 +4,7 @@
  
  // blame: jnml, labs.nic.cz
@@ -310,8 +364,10 @@
  
  import "sync/atomic"
  
---- a/storage/probe_test.go
-+++ b/storage/probe_test.go
+Index: golang-github-cznic-fileutil.git/storage/probe_test.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/storage/probe_test.go
++++ golang-github-cznic-fileutil.git/storage/probe_test.go
 @@ -4,7 +4,7 @@
  
  // blame: jnml, labs.nic.cz
@@ -321,8 +377,10 @@
  
  import (
  	"os"
---- a/storage/test_deps.go
-+++ b/storage/test_deps.go
+Index: golang-github-cznic-fileutil.git/storage/test_deps.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/storage/test_deps.go
++++ golang-github-cznic-fileutil.git/storage/test_deps.go
 @@ -4,7 +4,7 @@
  
  // blame: jnml, labs.nic.cz
diff --git a/debian/patches/remove-import-check.patch b/debian/patches/remove-import-check.patch
index e524d5c..fb577f7 100644
--- a/debian/patches/remove-import-check.patch
+++ b/debian/patches/remove-import-check.patch
@@ -1,5 +1,7 @@
---- a/fileutil.go
-+++ b/fileutil.go
+Index: golang-github-cznic-fileutil.git/fileutil.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/fileutil.go
++++ golang-github-cznic-fileutil.git/fileutil.go
 @@ -3,7 +3,7 @@
  // license that can be found in the LICENSE file.
  
@@ -8,10 +10,12 @@
 +package fileutil
  
  import (
- 	"fmt"
---- a/falloc/falloc.go
-+++ b/falloc/falloc.go
-@@ -12,7 +12,7 @@
+ 	"bufio"
+Index: golang-github-cznic-fileutil.git/falloc/falloc.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/falloc/falloc.go
++++ golang-github-cznic-fileutil.git/falloc/falloc.go
+@@ -12,7 +12,7 @@ The main incompletness is support for on
  
  */
  
@@ -20,9 +24,11 @@
  
  import (
  	"bytes"
---- a/hdb/hdb.go
-+++ b/hdb/hdb.go
-@@ -26,7 +26,7 @@
+Index: golang-github-cznic-fileutil.git/hdb/hdb.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/hdb/hdb.go
++++ golang-github-cznic-fileutil.git/hdb/hdb.go
+@@ -26,7 +26,7 @@ Conceptual analogy:
  
  	Delete	    free() the "memory" "pointed to" by handle.
  */
@@ -31,8 +37,10 @@
  
  import (
  	"modernc.org/fileutil/falloc"
---- a/storage/storage.go
-+++ b/storage/storage.go
+Index: golang-github-cznic-fileutil.git/storage/storage.go
+===================================================================
+--- golang-github-cznic-fileutil.git.orig/storage/storage.go
++++ golang-github-cznic-fileutil.git/storage/storage.go
 @@ -5,7 +5,7 @@
  // blame: jnml, labs.nic.cz
  
diff --git a/falloc/all_test.go b/falloc/all_test.go
index 6ce1d68..475a83a 100644
--- a/falloc/all_test.go
+++ b/falloc/all_test.go
@@ -1226,7 +1226,7 @@ func testFreeBlockList3(t *testing.T, n, mod int) {
 	}
 	f = reaudit(t, f, name)
 	del := map[int64]bool{}
-	for _ = range ha {
+	for range ha {
 		i := rng.Next()
 		if i%mod != 0 {
 			h := ha[i]
@@ -3013,7 +3013,7 @@ func TestMix(t *testing.T) {
 
 	t0 := time.Now()
 	// Alloc n block with upper half of content
-	for _ = range ha {
+	for range ha {
 		r := rng.Next()
 		c := content(b, int64(r))
 		c = c[len(c)/2:]
@@ -3027,7 +3027,7 @@ func TestMix(t *testing.T) {
 	f = reaudit(t, f, name)
 	t.Logf("size A %d for %d bytes (fill factor %3.1f%%)", f.atoms<<4, payload, 100*float64(payload)/float64(f.atoms<<4))
 	t0 = time.Now()
-	for _ = range ha {
+	for range ha {
 		r := rng.Next()
 		c := content(b, int64(r))
 		c = c[len(c)/2:]
@@ -3050,7 +3050,7 @@ func TestMix(t *testing.T) {
 	f = reaudit(t, f, name)
 	t.Logf("size B %d (freeing half of the blocks)", f.atoms<<4)
 	t0 = time.Now()
-	for _ = range ha {
+	for range ha {
 		r := rng.Next()
 		h := ha[r]
 		if h == 0 {
@@ -3068,7 +3068,7 @@ func TestMix(t *testing.T) {
 
 	// reloc extend
 	t0 = time.Now()
-	for _ = range ha {
+	for range ha {
 		r := rng.Next()
 		h := ha[r]
 		if h == 0 {
@@ -3089,7 +3089,7 @@ func TestMix(t *testing.T) {
 	t.Logf("size C %d for %d bytes (reallocated all used blocks to double size, fill factor %3.1f%%", f.atoms<<4, payload, 100*float64(payload)/float64(f.atoms<<4))
 
 	t0 = time.Now()
-	for _ = range ha {
+	for range ha {
 		r := rng.Next()
 		h := ha[r]
 		if h == 0 {
diff --git a/fileutil.go b/fileutil.go
index 991cef6..a751751 100644
--- a/fileutil.go
+++ b/fileutil.go
@@ -6,8 +6,10 @@
 package fileutil // import "modernc.org/fileutil"
 
 import (
+	"bufio"
 	"fmt"
 	"io"
+	"io/fs"
 	"os"
 	"path/filepath"
 	"runtime"
@@ -223,3 +225,136 @@ func nextInfix() string {
 	randmu.Unlock()
 	return strconv.Itoa(int(1e9 + r%1e9))[1:]
 }
+
+// CopyFile copies src in fsys, to dest in the OS file system, preserving
+// permissions and times where/when possible. If canOverwrite is not nil, it is
+// consulted whether a destination file can be overwritten. If canOverwrite is
+// nil then destination is overwritten if permissions allow that, otherwise the
+// function fails.
+func CopyFile(fsys fs.FS, dst, src string, canOverwrite func(fn string, fi os.FileInfo) bool) (n int64, rerr error) {
+	dstDir := filepath.Dir(dst)
+	di, err := os.Stat(dstDir)
+	switch {
+	case err != nil:
+		if !os.IsNotExist(err) {
+			return 0, err
+		}
+
+		if err := os.MkdirAll(dstDir, 0770); err != nil {
+			return 0, err
+		}
+	case err == nil:
+		if !di.IsDir() {
+			return 0, fmt.Errorf("cannot create directory, file exists: %s", dst)
+		}
+	}
+
+	s, err := fsys.Open(src)
+	if err != nil {
+		return 0, err
+	}
+
+	defer s.Close()
+
+	si, err := s.Stat()
+	if err != nil {
+		return 0, err
+	}
+
+	if si.IsDir() {
+		return 0, fmt.Errorf("cannot copy a directory: %s", src)
+	}
+
+	di, err = os.Stat(dst)
+	switch {
+	case err != nil && !os.IsNotExist(err):
+		return 0, err
+	case err == nil:
+		if di.IsDir() {
+			return 0, fmt.Errorf("cannot overwite a directory: %s", dst)
+		}
+
+		if canOverwrite != nil && !canOverwrite(dst, di) {
+			return 0, fmt.Errorf("cannot overwite: %s", dst)
+		}
+	}
+
+	r := bufio.NewReader(s)
+	d, err := os.Create(dst)
+
+	defer func() {
+		if err := d.Close(); err != nil && rerr == nil {
+			rerr = err
+			return
+		}
+
+		if err := os.Chmod(dst, si.Mode()); err != nil && rerr == nil {
+			rerr = err
+			return
+		}
+
+		if err := os.Chtimes(dst, si.ModTime(), si.ModTime()); err != nil && rerr == nil {
+			rerr = err
+			return
+		}
+	}()
+
+	w := bufio.NewWriter(d)
+
+	defer func() {
+		if err := w.Flush(); err != nil && rerr == nil {
+			rerr = err
+		}
+	}()
+
+	return io.Copy(w, r)
+}
+
+// CopyDir recursively copies src in fsys to dest in the OS file system,
+// preserving permissions and times where/when possible. If canOverwrite is not
+// nil, it is consulted whether a destination file can be overwritten. If
+// canOverwrite is nil then destination is overwritten if permissions allow
+// that, otherwise the function fails.
+func CopyDir(fsys fs.FS, dst, src string, canOverwrite func(fn string, fi os.FileInfo) bool) (files int, bytes int64, rerr error) {
+	s, err := fsys.Open(src)
+	if err != nil {
+		return 0, 0, err
+	}
+
+	si, err := s.Stat()
+	if err != nil {
+		return 0, 0, err
+	}
+
+	if err := s.Close(); err != nil {
+		return 0, 0, err
+	}
+
+	if !si.IsDir() {
+		return 0, 0, fmt.Errorf("cannot copy a file: %s", src)
+	}
+
+	return files, bytes, fs.WalkDir(fsys, src, func(path string, info fs.DirEntry, err error) error {
+		if err != nil {
+			return err
+		}
+
+		rel, err := filepath.Rel(src, path)
+		if err != nil {
+			return err
+		}
+
+		if info.IsDir() {
+			return os.MkdirAll(filepath.Join(dst, rel), 0770)
+		}
+
+		n, err := CopyFile(fsys, filepath.Join(dst, rel), path, canOverwrite)
+		if err != nil {
+			return err
+		}
+
+		files++
+		bytes += n
+		return nil
+	})
+}
diff --git a/fileutil_allarms.go b/fileutil_allarms.go
index 953ddce..539f27a 100644
--- a/fileutil_allarms.go
+++ b/fileutil_allarms.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (arm || arm64) && !windows && !openbsd && !plan9
 // +build arm arm64
 // +build !windows
 // +build !openbsd
diff --git a/fileutil_darwin.go b/fileutil_darwin.go
index 0418e42..7a71fa7 100644
--- a/fileutil_darwin.go
+++ b/fileutil_darwin.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !arm
-// +build !arm64
+//go:build !arm && !arm64
+// +build !arm,!arm64
 
 package fileutil // import "modernc.org/fileutil"
 
diff --git a/fileutil_dragonfly.go b/fileutil_dragonfly.go
index c26b260..3423cd3 100644
--- a/fileutil_dragonfly.go
+++ b/fileutil_dragonfly.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !arm
-// +build !arm64
+//go:build !arm && !arm64
+// +build !arm,!arm64
 
 package fileutil // import "modernc.org/fileutil"
 
diff --git a/fileutil_freebsd.go b/fileutil_freebsd.go
index b7c55e3..89707f1 100644
--- a/fileutil_freebsd.go
+++ b/fileutil_freebsd.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !arm
-// +build !arm64
+//go:build !arm && !arm64
+// +build !arm,!arm64
 
 package fileutil // import "modernc.org/fileutil"
 
diff --git a/fileutil_linux.go b/fileutil_linux.go
index e16362f..8aaf223 100644
--- a/fileutil_linux.go
+++ b/fileutil_linux.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !arm
-// +build !arm64
+//go:build !arm && !arm64
+// +build !arm,!arm64
 
 package fileutil // import "modernc.org/fileutil"
 
diff --git a/fileutil_netbsd.go b/fileutil_netbsd.go
index bf56205..de89bb8 100644
--- a/fileutil_netbsd.go
+++ b/fileutil_netbsd.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !arm
-// +build !arm64
+//go:build !arm && !arm64
+// +build !arm,!arm64
 
 package fileutil // import "modernc.org/fileutil"
 
diff --git a/fileutil_solaris.go b/fileutil_solaris.go
index 96ad80d..c81ae4c 100644
--- a/fileutil_solaris.go
+++ b/fileutil_solaris.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build go1.3
 // +build go1.3
 
 package fileutil // import "modernc.org/fileutil"
diff --git a/go.mod b/go.mod
index 6c2387a..f92792a 100644
--- a/go.mod
+++ b/go.mod
@@ -1 +1,7 @@
 module modernc.org/fileutil
+
+go 1.18
+
+require modernc.org/mathutil v1.5.0
+
+require github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..f79991e
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,4 @@
+github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
+github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
+modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
+modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
diff --git a/punch_test.go b/punch_test.go
index 7fe1881..1813da0 100644
--- a/punch_test.go
+++ b/punch_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 || amd64p32 || arm64 || arm64be || ppc64 || ppc64le || mips64 || mips64le || mips64p32 || mips64p32le || sparc64
 // +build amd64 amd64p32 arm64 arm64be ppc64 ppc64le mips64 mips64le mips64p32 mips64p32le sparc64
 
 package fileutil // import "modernc.org/fileutil"
diff --git a/storage/cache.go b/storage/cache.go
index 1031e87..a2a92df 100644
--- a/storage/cache.go
+++ b/storage/cache.go
@@ -296,7 +296,7 @@ func (c *Cache) writer() {
 }
 
 func (c *Cache) cleaner(limit int) {
-	for _ = range c.clean {
+	for range c.clean {
 		var item *list.Element
 		for {
 			c.lock.Lock() // X1+

More details

Full run details

Historical runs