From b076c62b382cdfee4a9a81803564c48ebfd5a8f6 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 20 Mar 2019 12:56:14 +0100 Subject: [PATCH 1/9] tempfile pattern test --- VERSION | 2 +- new.go | 1 + new_test.go | 11 +++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 0d91a54..9e11b32 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.0 +0.3.1 diff --git a/new.go b/new.go index ea5e973..cbf5b1f 100644 --- a/new.go +++ b/new.go @@ -38,6 +38,7 @@ type TempOpt struct { // directory where is temp file/dir create, empty string `""` (default) means TEMPDIR (`os.TempDir`) Dir string // name beginning with prefix + // if prefix includes a "*", the random string replaces the last "*". Prefix string } diff --git a/new_test.go b/new_test.go index 4bfa39b..13f4641 100644 --- a/new_test.go +++ b/new_test.go @@ -46,6 +46,17 @@ func TestTempFile(t *testing.T) { assert.Exactly(t, true, temp.Exists(), "new temp file exists") } +func TestTempFileWithPattern(t *testing.T) { + temp, err := NewTempFile(TempOpt{Prefix: "bla*.dat"}) + defer func() { + assert.NoError(t, temp.Remove()) + }() + + assert.NotNil(t, temp) + assert.Nil(t, err) + assert.Exactly(t, true, temp.Exists(), "new temp file exists") +} + func TestCwd(t *testing.T) { cwd, err := Cwd() assert.NotNil(t, cwd) From 03ccbe2b485216c32e772117e35dd9e376773226 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 20 Mar 2019 13:02:18 +0100 Subject: [PATCH 2/9] test by regexp --- new_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/new_test.go b/new_test.go index 13f4641..834a60a 100644 --- a/new_test.go +++ b/new_test.go @@ -55,6 +55,7 @@ func TestTempFileWithPattern(t *testing.T) { assert.NotNil(t, temp) assert.Nil(t, err) assert.Exactly(t, true, temp.Exists(), "new temp file exists") + assert.Regexp(t, "bla.+\\.dat$", temp.String()) } func TestCwd(t *testing.T) { From 840d9b38ba14f3c7d7ec2eb9fb581188d36b4389 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 20 Mar 2019 13:19:40 +0100 Subject: [PATCH 3/9] travis test in newer go versions --- .travis.yml | 2 ++ Makefile | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index bfd1c4c..79e0807 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,8 @@ go: - 1.7 - 1.8 - 1.9 + - 1.10 + - 1.11 install: - make setup diff --git a/Makefile b/Makefile index a0476a7..7749eb3 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ HELP?=$$(go run main.go --help 2>&1) VERSION?=$$(cat VERSION) -GO18?=$(shell go version | grep -E "go1\.[89]") +GONEWER?=$(shell go version | grep -E "go1\.1[01]") DEP?=$$(which dep) export GO15VENDOREXPERIMENT=1 @@ -20,8 +20,8 @@ setup: ## Install all the build and lint dependencies chmod +x $$GOPATH/bin/dep;\ fi dep ensure -ifeq ($(GO18),) - @echo no install metalinter, because metalinter need go1.8+ +ifeq ($(GONEWER),) + @echo no install metalinter, we need go1.10+ else go get -u github.com/alecthomas/gometalinter gometalinter --install @@ -40,7 +40,7 @@ fmt: ## gofmt and goimports all go files find . -name '*.go' -not -wholename './vendor/*' | while read -r file; do gofmt -w -s "$$file"; goimports -w "$$file"; done lint: ## Run all the linters -ifeq ($(GO18),) +ifeq ($(GONEWER),) @echo no run metalinter, because metalinter need go1.8+ else #https://github.com/golang/go/issues/19490 From 143450b8264d68324ee6505329163affd639ee9d Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 20 Mar 2019 15:43:17 +0100 Subject: [PATCH 4/9] change metalinter to golangci-linter (gometalinter is depracated - https://github.com/alecthomas/gometalinter) --- Makefile | 47 +++++++++++++++++------------------------------ 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index 7749eb3..9a45094 100644 --- a/Makefile +++ b/Makefile @@ -2,30 +2,38 @@ HELP?=$$(go run main.go --help 2>&1) VERSION?=$$(cat VERSION) GONEWER?=$(shell go version | grep -E "go1\.1[01]") DEP?=$$(which dep) +LINTER?=$$(which golangci-lint) +LINTER_VERSION=1.15.0 export GO15VENDOREXPERIMENT=1 ifeq ($(OS),Windows_NT) DEP_VERS=dep-windows-amd64.exe + LINTER_FILE=golangci-lint-$(LINTER_VERSION)-windows-amd64.zip + LINTER_UNPACK= >| app.zip; unzip -j app.zip -d $$GOPATH/bin; rm app.zip else ifeq ($(OS), Darwin) - DEP_VERS=dep-darwin-amd64 + DEP_VERS=darwin-amd64 + LINTER_FILE=golangci-lint-$(LINTER_VERSION)-darwin-amd64.tar.gz + LINTER_UNPACK= | tar xzf - -C $$GOPATH/bin --strip 1 "**/golangci-lint" else - DEP_VERS=dep-linux-amd64 + DEP_VERS=linux-amd64 + LINTER_FILE=golangci-lint-$(LINTER_VERSION)-linux-amd64.tar.gz + LINTER_UNPACK= | tar xzf - -C $$GOPATH/bin --strip 1 "**/golangci-lint" endif setup: ## Install all the build and lint dependencies go get -u golang.org/x/tools/cmd/cover go get -u github.com/robertkrimen/godocdown/godocdown + @if [ "$(DEP)" = "" ]; then\ curl -L https://github.com/golang/dep/releases/download/v0.4.1/$(DEP_VERS) >| $$GOPATH/bin/dep;\ chmod +x $$GOPATH/bin/dep;\ fi dep ensure -ifeq ($(GONEWER),) - @echo no install metalinter, we need go1.10+ -else - go get -u github.com/alecthomas/gometalinter - gometalinter --install -endif + + @if [ "$(LINTER)" = "" ]; then\ + curl -L https://github.com/golangci/golangci-lint/releases/download/v$(LINTER_VERSION)/$(LINTER_FILE) $(LINTER_UNPACK) ;\ + chmod +x $$GOPATH/bin/golangci-lint;\ + fi generate: ## Generate README.md godocdown >| README.md @@ -40,28 +48,7 @@ fmt: ## gofmt and goimports all go files find . -name '*.go' -not -wholename './vendor/*' | while read -r file; do gofmt -w -s "$$file"; goimports -w "$$file"; done lint: ## Run all the linters -ifeq ($(GONEWER),) - @echo no run metalinter, because metalinter need go1.8+ -else - #https://github.com/golang/go/issues/19490 - #--enable=vetshadow \ - - gometalinter --vendor --disable-all \ - --enable=deadcode \ - --enable=ineffassign \ - --enable=gosimple \ - --enable=staticcheck \ - --enable=gofmt \ - --enable=goimports \ - --enable=dupl \ - --enable=misspell \ - --enable=errcheck \ - --enable=vet \ - --deadline=10m \ - --enable=vetshadow \ - ./... - -endif + golangci-lint run ci: test lint ## Run all the tests and code checks From 1d279f48094ba227725843544ebb8dac35699946 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 20 Mar 2019 15:57:17 +0100 Subject: [PATCH 5/9] fix linux dep path --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9a45094..d0a047f 100644 --- a/Makefile +++ b/Makefile @@ -11,11 +11,11 @@ ifeq ($(OS),Windows_NT) LINTER_FILE=golangci-lint-$(LINTER_VERSION)-windows-amd64.zip LINTER_UNPACK= >| app.zip; unzip -j app.zip -d $$GOPATH/bin; rm app.zip else ifeq ($(OS), Darwin) - DEP_VERS=darwin-amd64 + DEP_VERS=dep-darwin-amd64 LINTER_FILE=golangci-lint-$(LINTER_VERSION)-darwin-amd64.tar.gz LINTER_UNPACK= | tar xzf - -C $$GOPATH/bin --strip 1 "**/golangci-lint" else - DEP_VERS=linux-amd64 + DEP_VERS=dep-linux-amd64 LINTER_FILE=golangci-lint-$(LINTER_VERSION)-linux-amd64.tar.gz LINTER_UNPACK= | tar xzf - -C $$GOPATH/bin --strip 1 "**/golangci-lint" endif @@ -25,7 +25,7 @@ setup: ## Install all the build and lint dependencies go get -u github.com/robertkrimen/godocdown/godocdown @if [ "$(DEP)" = "" ]; then\ - curl -L https://github.com/golang/dep/releases/download/v0.4.1/$(DEP_VERS) >| $$GOPATH/bin/dep;\ + curl -L https://github.com/golang/dep/releases/download/v0.5.1/$(DEP_VERS) >| $$GOPATH/bin/dep;\ chmod +x $$GOPATH/bin/dep;\ fi dep ensure From 12906d874099d0b3ef27924bf7c328617bf884dd Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 20 Mar 2019 16:03:45 +0100 Subject: [PATCH 6/9] wildcard support in tar --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index d0a047f..968fd6a 100644 --- a/Makefile +++ b/Makefile @@ -13,11 +13,11 @@ ifeq ($(OS),Windows_NT) else ifeq ($(OS), Darwin) DEP_VERS=dep-darwin-amd64 LINTER_FILE=golangci-lint-$(LINTER_VERSION)-darwin-amd64.tar.gz - LINTER_UNPACK= | tar xzf - -C $$GOPATH/bin --strip 1 "**/golangci-lint" + LINTER_UNPACK= | tar xzf - -C $$GOPATH/bin --wildcards --strip 1 "**/golangci-lint" else DEP_VERS=dep-linux-amd64 LINTER_FILE=golangci-lint-$(LINTER_VERSION)-linux-amd64.tar.gz - LINTER_UNPACK= | tar xzf - -C $$GOPATH/bin --strip 1 "**/golangci-lint" + LINTER_UNPACK= | tar xzf - -C $$GOPATH/bin --wildcards --strip 1 "**/golangci-lint" endif setup: ## Install all the build and lint dependencies From 5325c20202e9e8c946f7c26df69ddf2bbc9344b8 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 20 Mar 2019 16:13:29 +0100 Subject: [PATCH 7/9] fork tempFile function from go1.11 --- new.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/new.go b/new.go index cbf5b1f..a213888 100644 --- a/new.go +++ b/new.go @@ -53,7 +53,7 @@ type TempOpt struct { // temp.Remove() // func NewTempFile(options TempOpt) (p Path, err error) { - file, err := ioutil.TempFile(options.Dir, options.Prefix) + file, err := tempFile(options.Dir, options.Prefix) if err != nil { return nil, errors.Wrapf(err, "NewTempFile(%+v) fail", options) } From fd1d4c80437ffd1afc9d65425a1f14c971bbc8b1 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 20 Mar 2019 16:15:44 +0100 Subject: [PATCH 8/9] travis 1.10, 1.12 --- .travis.yml | 3 ++- tempfile.go | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 tempfile.go diff --git a/.travis.yml b/.travis.yml index 79e0807..66c8fe0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,9 @@ go: - 1.7 - 1.8 - 1.9 - - 1.10 + - "1.10" - 1.11 + - 1.12 install: - make setup diff --git a/tempfile.go b/tempfile.go new file mode 100644 index 0000000..d9ee48f --- /dev/null +++ b/tempfile.go @@ -0,0 +1,66 @@ +package pathutil + +// copy of go1.11 version of ioutil.TempFile +// https://golang.org/src/io/ioutil/tempfile.go?s=1419:1477#L40 +// because eerlier versions don't support pattern + +import ( + "os" + "path/filepath" + "strconv" + "strings" + "sync" + "time" +) + +// Random number state. +// We generate random temporary file names so that there's a good +// chance the file doesn't exist yet - keeps the number of tries in +// TempFile to a minimum. +var rand uint32 +var randmu sync.Mutex + +func reseed() uint32 { + return uint32(time.Now().UnixNano() + int64(os.Getpid())) +} + +func nextRandom() string { + randmu.Lock() + r := rand + if r == 0 { + r = reseed() + } + r = r*1664525 + 1013904223 // constants from Numerical Recipes + rand = r + randmu.Unlock() + return strconv.Itoa(int(1e9 + r%1e9))[1:] +} + +func tempFile(dir, pattern string) (f *os.File, err error) { + if dir == "" { + dir = os.TempDir() + } + + var prefix, suffix string + if pos := strings.LastIndex(pattern, "*"); pos != -1 { + prefix, suffix = pattern[:pos], pattern[pos+1:] + } else { + prefix = pattern + } + + nconflict := 0 + for i := 0; i < 10000; i++ { + name := filepath.Join(dir, prefix+nextRandom()+suffix) + f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600) + if os.IsExist(err) { + if nconflict++; nconflict > 10 { + randmu.Lock() + rand = reseed() + randmu.Unlock() + } + continue + } + break + } + return +} From 3f240d82b343201edbe7cd922e9f1592ebfdc712 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 20 Mar 2019 16:24:03 +0100 Subject: [PATCH 9/9] make ci don't run linter - use https://golangci.com integration instead --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 968fd6a..f3a377b 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ fmt: ## gofmt and goimports all go files lint: ## Run all the linters golangci-lint run -ci: test lint ## Run all the tests and code checks +ci: test ## Run all the tests but no linters - use https://golangci.com integration instead build: ## Build the app go build