Skip to content

Commit

Permalink
fix a problem with deleted files
Browse files Browse the repository at this point in the history
  • Loading branch information
0x5a17ed committed Nov 19, 2022
1 parent 3dc2cf1 commit 6ede7e6
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 9 deletions.
25 changes: 23 additions & 2 deletions pkg/floatingversion/floatingversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* language governing permissions and limitations under the License.
*/

package floatingversion
package floatingversion_test

import (
"errors"
Expand All @@ -30,6 +30,8 @@ import (
"github.com/go-git/go-git/v5/storage/memory"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/0x5a17ed/semverkzeug/pkg/floatingversion"
)

var signature = &object.Signature{
Expand Down Expand Up @@ -79,6 +81,24 @@ func oneCommitFixture(t *testing.T) (billy.Filesystem, *git.Repository) {
return fs, repo
}

func oneCommitFileDeletedFixture(t *testing.T) (billy.Filesystem, *git.Repository) {
fs, repo := emptyDirtyFixture(t)

wt, err := repo.Worktree()
require.NoError(t, err)

err = wt.AddWithOptions(&git.AddOptions{Path: "foo"})
require.NoError(t, err)

_, err = wt.Commit("asd", &git.CommitOptions{Author: signature, Committer: signature})
require.NoError(t, err)

err = fs.Remove("/foo")
require.NoError(t, err)

return fs, repo
}

func oneCommitDirtyFixture(t *testing.T) (billy.Filesystem, *git.Repository) {
fs, repo := oneCommitFixture(t)

Expand Down Expand Up @@ -145,6 +165,7 @@ func TestGetVersion(t *testing.T) {
{"empty-dirty", emptyDirtyFixture, `v0\.0\.1-dev\.0\.\d{14}`, assert.NoError},
{"one-commit-no-tag", oneCommitFixture, `v0\.0\.1-dev\.1`, assert.NoError},
{"one-commit-no-tag-dirty", oneCommitDirtyFixture, `v0\.0\.1-dev\.1\.\d{14}`, assert.NoError},
{"one-commit-no-tag-deleted-file", oneCommitFileDeletedFixture, `v0\.0\.1-dev\.1\.\d{14}`, assert.NoError},
{"one-tag", oneTaggedCommitRepositoryFixture, `v0\.1\.0`, assert.NoError},
{"one-tag-dirty", oneTaggedDirtyFixture, `v0\.1\.1-dev\.0\.\d{14}`, assert.NoError},
{"one-tag-one-commit", oneTagOneCommitFixture, `v0\.1\.1-dev\.1`, assert.NoError},
Expand All @@ -159,7 +180,7 @@ func TestGetVersion(t *testing.T) {
require.NoError(t, err)
}

gotVs, err := Get(repo, head, false)
gotVs, err := floatingversion.Get(repo, head, false)
if !tt.wantErr(t, err, fmt.Sprintf("Get(%v)", tt.repo)) {
return
}
Expand Down
31 changes: 24 additions & 7 deletions pkg/gitversions/lastmodtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,46 @@ package gitversions

import (
"errors"
"io/fs"
"path/filepath"
"time"

"github.com/go-git/go-billy/v5"
"github.com/go-git/go-git/v5"
)

var (
ErrNotDirty = errors.New("repository is clean")
)

func findModTime(vfs billy.Filesystem, fp string) (time.Time, error) {
for {
fi, err := vfs.Lstat(fp)
if err != nil {
if errors.Is(err, fs.ErrNotExist) && fp != "." {
// File was probably deleted. Try parent directory.
fp = filepath.Dir(fp)
continue
}
return time.Time{}, err
}
return fi.ModTime().UTC(), nil
}
}

func LastModificationTime(wt *git.Worktree, st git.Status) (*time.Time, error) {
var latestChange time.Time

for fp, fs := range st {
if fs.Worktree == git.Unmodified && fs.Staging == git.Unmodified {
for fp, fst := range st {
if fst.Worktree == git.Unmodified && fst.Staging == git.Unmodified {
continue
}

if fi, err := wt.Filesystem.Lstat(fp); err == nil {
if mtime := fi.ModTime(); mtime.After(latestChange) {
latestChange = mtime.UTC()
}
} else {
switch mtime, err := findModTime(wt.Filesystem, fp); {
case err != nil:
return nil, err
case mtime.After(latestChange):
latestChange = mtime
}
}

Expand Down

0 comments on commit 6ede7e6

Please sign in to comment.