diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/bench_test.go golang-github-djherbis-times-1.5.0/bench_test.go --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/bench_test.go 2018-03-22 10:08:15.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/bench_test.go 2021-04-27 23:32:16.000000000 +0000 @@ -19,6 +19,15 @@ t.ReportAllocs() } +func BenchmarkStatFile(t *testing.B) { + fileTest(t, func(f *os.File) { + for i := 0; i < t.N; i++ { + StatFile(f) + } + }) + t.ReportAllocs() +} + func BenchmarkStat(t *testing.B) { fileTest(t, func(f *os.File) { for i := 0; i < t.N; i++ { @@ -26,4 +35,31 @@ } }) t.ReportAllocs() +} + +func BenchmarkLstat(t *testing.B) { + fileTest(t, func(f *os.File) { + for i := 0; i < t.N; i++ { + Lstat(f.Name()) + } + }) + t.ReportAllocs() +} + +func BenchmarkOsStat(t *testing.B) { + fileTest(t, func(f *os.File) { + for i := 0; i < t.N; i++ { + os.Stat(f.Name()) + } + }) + t.ReportAllocs() +} + +func BenchmarkOsLstat(t *testing.B) { + fileTest(t, func(f *os.File) { + for i := 0; i < t.N; i++ { + os.Lstat(f.Name()) + } + }) + t.ReportAllocs() } diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/ctime_windows.go golang-github-djherbis-times-1.5.0/ctime_windows.go --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/ctime_windows.go 2018-03-22 10:08:15.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/ctime_windows.go 2021-04-27 23:32:16.000000000 +0000 @@ -7,6 +7,26 @@ "unsafe" ) +// Stat returns the Timespec for the given filename. +func Stat(name string) (Timespec, error) { + ts, err := platformSpecficStat(name) + if err == nil { + return ts, err + } + + return stat(name, os.Stat) +} + +// Lstat returns the Timespec for the given filename, and does not follow Symlinks. +func Lstat(name string) (Timespec, error) { + ts, err := platformSpecficLstat(name) + if err == nil { + return ts, err + } + + return stat(name, os.Lstat) +} + type timespecEx struct { atime mtime @@ -33,20 +53,48 @@ return t, nil } -const hasPlatformSpecificStat = true +func platformSpecficLstat(name string) (Timespec, error) { + if findProcErr != nil { + return nil, findProcErr + } + + isSym, err := isSymlink(name) + if err != nil { + return nil, err + } + + var attrs = uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS) + if isSym { + attrs |= syscall.FILE_FLAG_OPEN_REPARSE_POINT + } + + return openHandleAndStat(name, attrs) +} + +func isSymlink(name string) (bool, error) { + fi, err := os.Lstat(name) + if err != nil { + return false, err + } + return fi.Mode()&os.ModeSymlink != 0, nil +} func platformSpecficStat(name string) (Timespec, error) { if findProcErr != nil { return nil, findProcErr } + return openHandleAndStat(name, syscall.FILE_FLAG_BACKUP_SEMANTICS) +} + +func openHandleAndStat(name string, attrs uint32) (Timespec, error) { pathp, e := syscall.UTF16PtrFromString(name) if e != nil { return nil, e } h, e := syscall.CreateFile(pathp, syscall.FILE_WRITE_ATTRIBUTES, syscall.FILE_SHARE_WRITE, nil, - syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0) + syscall.OPEN_EXISTING, attrs, 0) if e != nil { return nil, e } @@ -92,10 +140,9 @@ r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(handle), uintptr(fileBasicInfoClass), uintptr(unsafe.Pointer(data)), unsafe.Sizeof(*data), 0, 0) if r1 == 0 { + err = syscall.EINVAL if e1 != 0 { err = error(e1) - } else { - err = syscall.EINVAL } } return diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/changelog golang-github-djherbis-times-1.5.0/debian/changelog --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/changelog 2021-01-08 14:00:12.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/debian/changelog 2021-09-07 19:09:57.000000000 +0000 @@ -1,9 +1,37 @@ -golang-github-djherbis-times (1.0.1+git20170215.d25002f-1.1) unstable; urgency=medium +golang-github-djherbis-times (1.5.0-1) unstable; urgency=medium - * Non maintainer upload by the Reproducible Builds team. - * No source change upload to rebuild on buildd with .buildinfo files. + [ Alexandre Viau ] + * Point Vcs-* urls to salsa.debian.org. - -- Holger Levsen Fri, 08 Jan 2021 15:00:12 +0100 + [ Debian Janitor ] + * Bump debhelper from old 11 to 12. + Fixes: lintian: package-uses-old-debhelper-compat-version + See-also: https://lintian.debian.org/tags/package-uses-old-debhelper-compat-version.html + * Set debhelper-compat version in Build-Depends. + Fixes: lintian: uses-debhelper-compat-file + See-also: https://lintian.debian.org/tags/uses-debhelper-compat-file.html + * Set upstream metadata fields: Bug-Database, Bug-Submit, Repository, Repository-Browse. + Fixes: lintian: upstream-metadata-file-is-missing + See-also: https://lintian.debian.org/tags/upstream-metadata-file-is-missing.html + + [ Dr. Tobias Quathamer ] + * New upstream version 1.5.0 + * Use debhelper v13 + * Fix typo in package description + * Add DEP-14 layout to gbp.conf + * Update d/watch to version 4 + * Add Multi-Arch: foreign + * Add Rules-Requires-Root: no + * Exclude example binary from the package build + * Update gitlab-ci.yml + * Update Maintainer team address + * Update Section: to golang + * Update to Standards-Version to 4.6.0, no changes needed + * Add Built-Using field to d/control + * Update d/copyright + * Use a build directory and fix typo in DH_GOLANG_EXCLUDES + + -- Dr. Tobias Quathamer Tue, 07 Sep 2021 21:09:57 +0200 golang-github-djherbis-times (1.0.1+git20170215.d25002f-1) unstable; urgency=medium diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/compat golang-github-djherbis-times-1.5.0/debian/compat --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/compat 2018-03-22 10:08:15.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/debian/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -11 diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/control golang-github-djherbis-times-1.5.0/debian/control --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/control 2018-03-22 10:08:15.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/debian/control 2021-09-07 15:39:33.000000000 +0000 @@ -1,22 +1,25 @@ Source: golang-github-djherbis-times -Section: devel +Section: golang Priority: optional -Maintainer: Debian Go Packaging Team +Maintainer: Debian Go Packaging Team Uploaders: Dr. Tobias Quathamer -Build-Depends: debhelper (>= 11~), +Build-Depends: debhelper-compat (= 13), dh-golang, golang-any -Standards-Version: 4.1.3 +Standards-Version: 4.6.0 Homepage: https://github.com/djherbis/times -Vcs-Browser: https://anonscm.debian.org/cgit/pkg-go/packages/golang-github-djherbis-times.git -Vcs-Git: https://anonscm.debian.org/git/pkg-go/packages/golang-github-djherbis-times.git +Vcs-Browser: https://salsa.debian.org/go-team/packages/golang-github-djherbis-times +Vcs-Git: https://salsa.debian.org/go-team/packages/golang-github-djherbis-times.git XS-Go-Import-Path: github.com/djherbis/times Testsuite: autopkgtest-pkg-go +Rules-Requires-Root: no Package: golang-github-djherbis-times-dev Architecture: all +Multi-Arch: foreign Depends: ${shlibs:Depends}, ${misc:Depends} +Built-Using: ${misc:Built-Using} Description: file times (atime, mtime, ctime, btime) - Go has a hidden time functions for most platforms, this repo makes + Go has hidden time functions for most platforms, this repo makes them accessible. diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/copyright golang-github-djherbis-times-1.5.0/debian/copyright --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/copyright 2018-03-22 10:08:15.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/debian/copyright 2021-09-07 18:28:36.000000000 +0000 @@ -8,7 +8,7 @@ License: Expat Files: debian/* -Copyright: 2018 Dr. Tobias Quathamer +Copyright: 2018--2021 Dr. Tobias Quathamer License: Expat Comment: Debian packaging is licensed under the same terms as upstream diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/gbp.conf golang-github-djherbis-times-1.5.0/debian/gbp.conf --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/gbp.conf 2018-03-22 10:08:15.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/debian/gbp.conf 2021-09-07 15:39:33.000000000 +0000 @@ -1,2 +1,3 @@ [DEFAULT] -pristine-tar = True +debian-branch = debian/sid +dist = DEP14 diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/gitlab-ci.yml golang-github-djherbis-times-1.5.0/debian/gitlab-ci.yml --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/gitlab-ci.yml 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/debian/gitlab-ci.yml 2021-09-07 15:39:33.000000000 +0000 @@ -0,0 +1,26 @@ +# auto-generated, DO NOT MODIFY. +# The authoritative copy of this file lives at: +# https://salsa.debian.org/go-team/ci/blob/master/config/gitlabciyml.go + +image: stapelberg/ci2 + +test_the_archive: + artifacts: + paths: + - before-applying-commit.json + - after-applying-commit.json + script: + # Create an overlay to discard writes to /srv/gopath/src after the build: + - "rm -rf /cache/overlay/{upper,work}" + - "mkdir -p /cache/overlay/{upper,work}" + - "mount -t overlay overlay -o lowerdir=/srv/gopath/src,upperdir=/cache/overlay/upper,workdir=/cache/overlay/work /srv/gopath/src" + - "export GOPATH=/srv/gopath" + - "export GOCACHE=/cache/go" + # Build the world as-is: + - "ci-build -exemptions=/var/lib/ci-build/exemptions.json > before-applying-commit.json" + # Copy this package into the overlay: + - "GBP_CONF_FILES=:debian/gbp.conf gbp buildpackage --git-no-pristine-tar --git-ignore-branch --git-ignore-new --git-export-dir=/tmp/export --git-no-overlay --git-tarball-dir=/nonexistant --git-cleaner=/bin/true --git-builder='dpkg-buildpackage -S -d --no-sign'" + - "pgt-gopath -dsc /tmp/export/*.dsc" + # Rebuild the world: + - "ci-build -exemptions=/var/lib/ci-build/exemptions.json > after-applying-commit.json" + - "ci-diff before-applying-commit.json after-applying-commit.json" diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/rules golang-github-djherbis-times-1.5.0/debian/rules --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/rules 2018-03-22 10:08:15.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/debian/rules 2021-09-07 18:58:50.000000000 +0000 @@ -1,4 +1,7 @@ #!/usr/bin/make -f +# Do not install the example binary +export DH_GOLANG_EXCLUDES := example + %: - dh $@ --buildsystem=golang --with=golang + dh $@ --builddirectory=_build --buildsystem=golang --with=golang diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/upstream/metadata golang-github-djherbis-times-1.5.0/debian/upstream/metadata --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/upstream/metadata 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/debian/upstream/metadata 2021-09-07 14:55:36.000000000 +0000 @@ -0,0 +1,4 @@ +Bug-Database: https://github.com/djherbis/times/issues +Bug-Submit: https://github.com/djherbis/times/issues/new +Repository: https://github.com/djherbis/times.git +Repository-Browse: https://github.com/djherbis/times diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/watch golang-github-djherbis-times-1.5.0/debian/watch --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/debian/watch 2018-03-22 10:08:15.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/debian/watch 2021-09-07 15:39:33.000000000 +0000 @@ -1,4 +1,4 @@ -version=3 -opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/golang-github-djherbis-times-\$1\.tar\.gz/,\ -uversionmangle=s/(\d)[_\.\-\+]?(RC|rc|pre|dev|beta|alpha)[.]?(\d*)$/\$1~\$2\$3/ \ - https://github.com/djherbis/times/tags .*/v?(\d\S*)\.tar\.gz +version=4 +opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%@PACKAGE@-$1.tar.gz%,\ + uversionmangle=s/(\d)[_\.\-\+]?(RC|rc|pre|dev|beta|alpha)[.]?(\d*)$/$1~$2$3/" \ + https://github.com/djherbis/times/tags .*/v?(\d\S*)\.tar\.gz debian diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/example/main.go golang-github-djherbis-times-1.5.0/example/main.go --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/example/main.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/example/main.go 2021-04-27 23:32:16.000000000 +0000 @@ -0,0 +1,96 @@ +package main + +import ( + "fmt" + "io/ioutil" + "log" + "os" + "path/filepath" + "time" + + "github.com/djherbis/times" +) + +func main() { + switch len(os.Args) { + case 1: + tempFile() + fmt.Println() + tempDir() + + default: + printTimes(os.Args[1]) + } +} + +func tempDir() { + name, err := ioutil.TempDir("", "") + if err != nil { + log.Fatal(err) + } + defer os.Remove(name) + fmt.Println("# DIR: " + name) + + symname := filepath.Join(filepath.Dir(name), "sym-"+filepath.Base(name)) + if err := os.Symlink(name, symname); err != nil { + log.Fatal(err) + } + defer os.Remove(symname) + + newAtime := time.Now().Add(-10 * time.Second) + newMtime := time.Now().Add(10 * time.Second) + if err := os.Chtimes(name, newAtime, newMtime); err != nil { + log.Fatal(err) + } + + printTimes(symname) +} + +func tempFile() { + f, err := ioutil.TempFile("", "") + if err != nil { + log.Fatal(err) + } + defer os.Remove(f.Name()) + defer f.Close() + fmt.Println("# FILE: " + f.Name()) + + symname := filepath.Join(filepath.Dir(f.Name()), "sym-"+filepath.Base(f.Name())) + if err := os.Symlink(f.Name(), symname); err != nil { + log.Fatal(err) + } + defer os.Remove(symname) + + newAtime := time.Now().Add(-10 * time.Second) + newMtime := time.Now().Add(10 * time.Second) + if err := os.Chtimes(f.Name(), newAtime, newMtime); err != nil { + log.Fatal(err) + } + + printTimes(symname) +} + +func printTimes(name string) { + fmt.Println("## Stat:", name) + printTimespec(times.Stat(name)) + + fmt.Println("\n## Lstat:", name) + printTimespec(times.Lstat(name)) +} + +func printTimespec(ts times.Timespec, err error) { + if err != nil { + log.Fatal(err) + } + + fmt.Println("AccessTime:", ts.AccessTime()) + fmt.Println("ModTime:", ts.ModTime()) + + if ts.HasChangeTime() { + fmt.Println("ChangeTime:", ts.ChangeTime()) + } + + if ts.HasBirthTime() { + fmt.Println("BirthTime:", ts.BirthTime()) + } +} diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/go.mod golang-github-djherbis-times-1.5.0/go.mod --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/go.mod 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/go.mod 2021-04-27 23:32:16.000000000 +0000 @@ -0,0 +1,3 @@ +module github.com/djherbis/times + +go 1.16 diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/js.cover.dockerfile golang-github-djherbis-times-1.5.0/js.cover.dockerfile --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/js.cover.dockerfile 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/js.cover.dockerfile 2021-04-27 23:32:16.000000000 +0000 @@ -0,0 +1,9 @@ +FROM golang:1.16 + +RUN curl -sL https://deb.nodesource.com/setup_8.x | bash +RUN apt-get install --yes nodejs + +WORKDIR /go/src/github.com/djherbis/times +COPY . . + +RUN GO111MODULE=auto GOOS=js GOARCH=wasm go test -covermode=count -coverprofile=profile.cov -exec="$(go env GOROOT)/misc/wasm/go_js_wasm_exec" diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/js.cover.sh golang-github-djherbis-times-1.5.0/js.cover.sh --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/js.cover.sh 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/js.cover.sh 2021-04-27 23:32:16.000000000 +0000 @@ -0,0 +1,7 @@ +#!/bin/bash +set -e + +docker build -f js.cover.dockerfile -t js.cover.djherbis.times . +docker create --name js.cover.djherbis.times js.cover.djherbis.times +docker cp js.cover.djherbis.times:/go/src/github.com/djherbis/times/profile.cov . +docker rm -v js.cover.djherbis.times \ No newline at end of file diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/README.md golang-github-djherbis-times-1.5.0/README.md --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/README.md 2018-03-22 10:08:15.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/README.md 2021-04-27 23:32:16.000000000 +0000 @@ -45,12 +45,12 @@ Supported Times ------------ -| | windows | linux | solaris | dragonfly | nacl | freebsd | darwin | netbsd | openbsd | plan9 | -|:-----:|:-------:|:-----:|:-------:|:---------:|:------:|:-------:|:----:|:------:|:-------:|:-----:| -| atime | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| mtime | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| ctime | ✓* | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | -| btime | ✓ | | | | | ✓ | ✓| ✓ | +| | windows | linux | solaris | dragonfly | nacl | freebsd | darwin | netbsd | openbsd | plan9 | js | aix | +|:-----:|:-------:|:-----:|:-------:|:---------:|:------:|:-------:|:----:|:------:|:-------:|:-----:|:-----:|:-----:| +| atime | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| mtime | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| ctime | ✓* | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | ✓ | ✓ | +| btime | ✓ | | | | | ✓ | ✓| ✓ | | | * Windows XP does not have ChangeTime so HasChangeTime = false, however Vista onward does have ChangeTime so Timespec.HasChangeTime() will @@ -60,5 +60,5 @@ Installation ------------ ```sh -go get github.com/djherbis/times +go get -u github.com/djherbis/times ``` diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/times_aix.go golang-github-djherbis-times-1.5.0/times_aix.go --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/times_aix.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/times_aix.go 2021-04-27 23:32:16.000000000 +0000 @@ -0,0 +1,39 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// https://golang.org/src/os/stat_aix.go + +package times + +import ( + "os" + "syscall" + "time" +) + +// HasChangeTime and HasBirthTime are true if and only if +// the target OS supports them. +const ( + HasChangeTime = true + HasBirthTime = false +) + +type timespec struct { + atime + mtime + ctime + nobtime +} + +func timespecToTime(ts syscall.StTimespec_t) time.Time { + return time.Unix(int64(ts.Sec), int64(ts.Nsec)) +} + +func getTimespec(fi os.FileInfo) (t timespec) { + stat := fi.Sys().(*syscall.Stat_t) + t.atime.v = timespecToTime(stat.Atim) + t.mtime.v = timespecToTime(stat.Mtim) + t.ctime.v = timespecToTime(stat.Ctim) + return t +} diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/times.go golang-github-djherbis-times-1.5.0/times.go --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/times.go 2018-03-22 10:08:15.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/times.go 2021-04-27 23:32:16.000000000 +0000 @@ -11,15 +11,10 @@ return getTimespec(fi) } -// Stat returns the Timespec for the given filename. -func Stat(name string) (Timespec, error) { - if hasPlatformSpecificStat { - if ts, err := platformSpecficStat(name); err == nil { - return ts, nil - } - } +type statFunc func(string) (os.FileInfo, error) - fi, err := os.Stat(name) +func stat(name string, sf statFunc) (Timespec, error) { + fi, err := sf(name) if err != nil { return nil, err } diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/times_js.go golang-github-djherbis-times-1.5.0/times_js.go --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/times_js.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/times_js.go 2021-04-27 23:32:16.000000000 +0000 @@ -0,0 +1,41 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// https://golang.org/src/os/stat_nacljs.go + +// +build js,wasm + +package times + +import ( + "os" + "syscall" + "time" +) + +// HasChangeTime and HasBirthTime are true if and only if +// the target OS supports them. +const ( + HasChangeTime = true + HasBirthTime = false +) + +type timespec struct { + atime + mtime + ctime + nobtime +} + +func timespecToTime(sec, nsec int64) time.Time { + return time.Unix(sec, nsec) +} + +func getTimespec(fi os.FileInfo) (t timespec) { + stat := fi.Sys().(*syscall.Stat_t) + t.atime.v = timespecToTime(stat.Atime, stat.AtimeNsec) + t.mtime.v = timespecToTime(stat.Mtime, stat.MtimeNsec) + t.ctime.v = timespecToTime(stat.Ctime, stat.CtimeNsec) + return t +} diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/times_nacl.go golang-github-djherbis-times-1.5.0/times_nacl.go --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/times_nacl.go 2018-03-22 10:08:15.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/times_nacl.go 2021-04-27 23:32:16.000000000 +0000 @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// http://golang.org/src/os/stat_nacl.go +// https://golang.org/src/os/stat_nacljs.go package times diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/times_test.go golang-github-djherbis-times-1.5.0/times_test.go --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/times_test.go 2018-03-22 10:08:15.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/times_test.go 2021-04-27 23:32:16.000000000 +0000 @@ -2,13 +2,14 @@ import ( "os" + "path/filepath" "testing" "time" ) func TestStat(t *testing.T) { - fileTest(t, func(f *os.File) { - ts, err := Stat(f.Name()) + fileAndDirTest(t, func(name string) { + ts, err := Stat(name) if err != nil { t.Error(err.Error()) } @@ -17,8 +18,8 @@ } func TestGet(t *testing.T) { - fileTest(t, func(f *os.File) { - fi, err := os.Stat(f.Name()) + fileAndDirTest(t, func(name string) { + fi, err := os.Stat(name) if err != nil { t.Error(err.Error()) } @@ -26,6 +27,63 @@ }) } +func TestStatFile(t *testing.T) { + fileTest(t, func(f *os.File) { + ts, err := StatFile(f) + if err != nil { + t.Error(err.Error()) + } + timespecTest(ts, newInterval(time.Now(), time.Second), t) + }) +} + +func TestStatFileErr(t *testing.T) { + fileTest(t, func(f *os.File) { + f.Close() + + _, err := StatFile(f) + if err == nil { + t.Error("got nil err, but err was expected!") + } + }) +} + +type tsFunc func(string) (Timespec, error) + +var offsetTime = -10 * time.Second + +func TestStatSymlink(t *testing.T) { + testStatSymlink(Stat, time.Now().Add(offsetTime), t) +} + +func TestLstatSymlink(t *testing.T) { + testStatSymlink(Lstat, time.Now(), t) +} + +func testStatSymlink(sf tsFunc, expectTime time.Time, t *testing.T) { + fileAndDirTest(t, func(name string) { + start := time.Now() + + symname := filepath.Join(filepath.Dir(name), "sym-"+filepath.Base(name)) + if err := os.Symlink(name, symname); err != nil { + t.Error(err.Error()) + } + defer os.Remove(symname) + + // modify the realFileTime so symlink and real file see diff values. + realFileTime := start.Add(offsetTime) + if err := os.Chtimes(name, realFileTime, realFileTime); err != nil { + t.Error(err.Error()) + } + + ts, err := sf(symname) + if err != nil { + t.Error(err.Error()) + } + timespecTest(ts, newInterval(expectTime, time.Second), t, Timespec.AccessTime, Timespec.ModTime) + }) +} + func TestStatErr(t *testing.T) { _, err := Stat("badfile?") if err == nil { @@ -33,6 +91,13 @@ } } +func TestLstatErr(t *testing.T) { + _, err := Lstat("badfile?") + if err == nil { + t.Error("expected an error") + } +} + func TestCheat(t *testing.T) { // not all times are available for all platforms // this allows us to get 100% test coverage for platforms which do not have @@ -47,19 +112,35 @@ b.BirthTime() } + var paniced = false var nc noctime func() { if !nc.HasChangeTime() { - defer func() { recover() }() + defer func() { + recover() + paniced = true + }() } nc.ChangeTime() }() + if !paniced { + t.Error("expected panic") + } + + paniced = false var nb nobtime func() { if !nb.HasBirthTime() { - defer func() { recover() }() + defer func() { + recover() + paniced = true + }() } nb.BirthTime() }() + + if !paniced { + t.Error("expected panic") + } } diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/times_windows_test.go golang-github-djherbis-times-1.5.0/times_windows_test.go --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/times_windows_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/times_windows_test.go 2021-04-27 23:32:16.000000000 +0000 @@ -0,0 +1,54 @@ +package times + +import ( + "errors" + "os" + "syscall" + "testing" + "time" +) + +func TestStatFileProcErr(t *testing.T) { + fileTest(t, func(f *os.File) { + findProcErr = errors.New("fake error") + defer func() { findProcErr = nil }() + + _, err := StatFile(f) + if err == nil { + t.Error("got nil err, but err was expected!") + } + }) +} + +func TestStatBadNameErr(t *testing.T) { + _, err := platformSpecficStat(string([]byte{0})) + if err != syscall.EINVAL { + t.Error(err) + } +} + +func TestStatProcErrFallback(t *testing.T) { + fileAndDirTest(t, func(name string) { + findProcErr = errors.New("fake error") + defer func() { findProcErr = nil }() + + ts, err := Stat(name) + if err != nil { + t.Error(err.Error()) + } + timespecTest(ts, newInterval(time.Now(), time.Second), t) + }) +} + +func TestLstatProcErrFallback(t *testing.T) { + fileAndDirTest(t, func(name string) { + findProcErr = errors.New("fake error") + defer func() { findProcErr = nil }() + + ts, err := Lstat(name) + if err != nil { + t.Error(err.Error()) + } + timespecTest(ts, newInterval(time.Now(), time.Second), t) + }) +} diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/.travis.sh golang-github-djherbis-times-1.5.0/.travis.sh --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/.travis.sh 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/.travis.sh 2021-04-27 23:32:16.000000000 +0000 @@ -0,0 +1,28 @@ +#!/bin/bash +set -e + +script() { + if [ "${TRAVIS_PULL_REQUEST}" == "false" ]; + then + COVERALLS_PARALLEL=true + + if [ ! -z "$JS" ]; + then + bash js.cover.sh + else + go test -covermode=count -coverprofile=profile.cov + fi + + go get github.com/axw/gocov/gocov github.com/mattn/goveralls golang.org/x/tools/cmd/cover + $HOME/gopath/bin/goveralls --coverprofile=profile.cov -service=travis-ci + fi + + if [ -z "$JS" ]; + then + go get golang.org/x/lint/golint && golint ./... + go vet + go test -bench=.* -v ./... + fi +} + +"$@" \ No newline at end of file diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/.travis.yml golang-github-djherbis-times-1.5.0/.travis.yml --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/.travis.yml 2018-03-22 10:08:15.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/.travis.yml 2021-04-27 23:32:16.000000000 +0000 @@ -1,22 +1,28 @@ language: go -go: -- 1.7 -before_install: -- go get -u github.com/golang/lint/golint -- go get github.com/axw/gocov/gocov -- go get github.com/mattn/goveralls -- if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; - fi -script: -- '[ "${TRAVIS_PULL_REQUEST}" != "false" ] || $HOME/gopath/bin/goveralls -service=travis-ci - -repotoken $COVERALLS_TOKEN' -- "$HOME/gopath/bin/golint ./..." -- go vet -- go test -bench=.* -v ./... +matrix: + include: + - os: linux + go: tip + - os: linux + go: tip + env: + - JS=1 + - os: osx + go: tip + - os: windows + go: 1.x +#Added power jobs + - os: linux + go: tip + arch: ppc64le + - os: linux + go: tip + arch: ppc64le + env: + - JS=1 +script: bash .travis.sh script notifications: + webhooks: https://coveralls.io/webhook email: on_success: never on_failure: change -env: - global: - secure: JLdvT4dl+oifYzbQN5I0G8mZi1KVj3D3zTC8N3D9eLEvHY26QggS2I6M5CNAYkbGSB2RDp7gZLHui8zVzvudD5GuxP2xZe+WN4+n9lf+jLnCuB77ZjKCuDa1+Wg/o466L4PK0BaiTQahbk9qsDNOdfTzXXLEnqBDo1WtvLJ1mn02pL5Wyt3aAA4yeK3z7eUYFNxyi/KJ22bwhjIv6Qa9RHT7ZfR6x9YQSGeLZIWPUx5S+vmySd7sM7gRTw+lRmR/i0PNMHjlOKoyedAT8YLAWX28xgPtc7E5j+pBm6ZmDcN79tTelhiAS9uifEKkdsugZZjfnLBl9gks19bmXP4mxUIo1iKQgIbKVs7R/QMdH7RXW+isfQP/vtk6SNC86os+r7tSJ1EOtF1cZfQ7H4o2RevA3VVTVZ+45gnrK8v00eckbLmsGGho7RGORIt+JGvD0oe84dXdk/lFtBTzWhOJn2Ujlm6L3z3r/YMN2CGFfH5JGpsUKJh1uRzJ5MPqkdxRwcGrtN4DGC1L8tRMfYPo06dQxa8p4TnbYQSZ6qwuVZMMcNvr9c/edwLizMh9KXivPodmHpLAMAUPSyWLtF8pp305DUhajpRsUEvTvs082KJAK4bUNE+AxRIBwtuB0Z2r0DpgfVwAUIXh42l9RDxEA1mwUyX2EKolyRqxQGPv9NQ= diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/use_generic_stat.go golang-github-djherbis-times-1.5.0/use_generic_stat.go --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/use_generic_stat.go 2018-03-22 10:08:15.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/use_generic_stat.go 2021-04-27 23:32:16.000000000 +0000 @@ -2,9 +2,23 @@ package times -const hasPlatformSpecificStat = false +import "os" -// do not use, only here to prevent "undefined" method error. -func platformSpecficStat(name string) (Timespec, error) { - return nil, nil +// Stat returns the Timespec for the given filename. +func Stat(name string) (Timespec, error) { + return stat(name, os.Stat) +} + +// Lstat returns the Timespec for the given filename, and does not follow Symlinks. +func Lstat(name string) (Timespec, error) { + return stat(name, os.Lstat) +} + +// StatFile returns the Timespec for the given *os.File. +func StatFile(file *os.File) (Timespec, error) { + fi, err := file.Stat() + if err != nil { + return nil, err + } + return getTimespec(fi), nil } diff -Nru golang-github-djherbis-times-1.0.1+git20170215.d25002f/util_test.go golang-github-djherbis-times-1.5.0/util_test.go --- golang-github-djherbis-times-1.0.1+git20170215.d25002f/util_test.go 2018-03-22 10:08:15.000000000 +0000 +++ golang-github-djherbis-times-1.5.0/util_test.go 2021-04-27 23:32:16.000000000 +0000 @@ -3,6 +3,8 @@ import ( "io/ioutil" "os" + "reflect" + "runtime" "testing" "time" ) @@ -20,31 +22,60 @@ return !findTime.Before(t.start) && !findTime.After(t.end) } +func fileAndDirTest(t testing.TB, testFunc func(name string)) { + filenameTest(t, testFunc) + dirTest(t, testFunc) +} + // creates a file and cleans it up after the test is run. func fileTest(t testing.TB, testFunc func(f *os.File)) { f, err := ioutil.TempFile("", "") if err != nil { - t.Error(err) + t.Fatal(err) } defer os.Remove(f.Name()) defer f.Close() testFunc(f) } -func timespecTest(ts Timespec, r timeRange, t testing.TB) { - if !r.Contains(ts.AccessTime()) { - t.Errorf("expected %s to be in range: %s\n", ts.AccessTime(), r.start) - } +func filenameTest(t testing.TB, testFunc func(filename string)) { + fileTest(t, func(f *os.File) { + testFunc(f.Name()) + }) +} - if !r.Contains(ts.ModTime()) { - t.Errorf("expected %s to be in range: %s\n", ts.ModTime(), r.start) +// creates a dir and cleans it up after the test is run. +func dirTest(t testing.TB, testFunc func(dirname string)) { + dirname, err := ioutil.TempDir("", "") + if err != nil { + t.Fatal(err) } + defer os.Remove(dirname) + testFunc(dirname) +} + +type timeFetcher func(Timespec) time.Time - if ts.HasChangeTime() && !r.Contains(ts.ChangeTime()) { - t.Errorf("expected %s to be in range: %s\n", ts.ChangeTime(), r.start) +func timespecTest(ts Timespec, r timeRange, t testing.TB, getTimes ...timeFetcher) { + if len(getTimes) == 0 { + getTimes = append(getTimes, Timespec.AccessTime, Timespec.ModTime) + + if ts.HasChangeTime() { + getTimes = append(getTimes, Timespec.ChangeTime) + } + + if ts.HasBirthTime() { + getTimes = append(getTimes, Timespec.BirthTime) + } } - if ts.HasBirthTime() && !r.Contains(ts.BirthTime()) { - t.Errorf("expected %s to be in range: %s\n", ts.BirthTime(), r.start) + for _, getTime := range getTimes { + if !r.Contains(getTime(ts)) { + t.Errorf("expected %s=%s to be in range: \n[%s, %s]\n", GetFunctionName(getTime), getTime(ts), r.start, r.end) + } } } + +func GetFunctionName(i interface{}) string { + return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() +}