diff --git a/internal/provider/data_source_commit_test.go b/internal/provider/data_source_commit_test.go index 8cef525..7391bb4 100644 --- a/internal/provider/data_source_commit_test.go +++ b/internal/provider/data_source_commit_test.go @@ -98,6 +98,97 @@ func TestDataSourceGitCommit_MultipleFiles(t *testing.T) { }) } +func TestDataSourceGitCommit_Issue231_SingleCommit(t *testing.T) { + t.Parallel() + directory, repository := testutils.CreateRepository(t) + testutils.TestConfig(t, repository) + worktree := testutils.GetRepositoryWorktree(t, repository) + fileName1 := "some-file" + fileName2 := "other-file" + testutils.WriteFileInWorktree(t, worktree, fileName1) + testutils.WriteFileInWorktree(t, worktree, fileName2) + testutils.GitAdd(t, worktree, fileName1) + //testutils.GitAdd(t, worktree, fileName2) // do not add second file to staging area + commit := testutils.GitCommit(t, worktree) + + resource.UnitTest(t, resource.TestCase{ + ProtoV6ProviderFactories: testutils.ProviderFactories(), + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(` + data "git_commit" "test" { + directory = "%s" + revision = "%s" + } + `, directory, commit.String()), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.git_commit.test", "directory", directory), + resource.TestCheckResourceAttr("data.git_commit.test", "id", commit.String()), + resource.TestCheckResourceAttr("data.git_commit.test", "revision", commit.String()), + resource.TestCheckResourceAttr("data.git_commit.test", "sha1", commit.String()), + resource.TestCheckResourceAttr("data.git_commit.test", "signature", ""), + resource.TestCheckResourceAttr("data.git_commit.test", "files.#", "1"), + resource.TestCheckResourceAttr("data.git_commit.test", "files.0", "some-file"), + resource.TestCheckResourceAttrWith("data.git_commit.test", "message", testutils.CheckMinLength(1)), + resource.TestCheckResourceAttrWith("data.git_commit.test", "tree_sha1", testutils.CheckMinLength(1)), + resource.TestCheckResourceAttrWith("data.git_commit.test", "author.name", testutils.CheckMinLength(1)), + resource.TestCheckResourceAttrWith("data.git_commit.test", "author.email", testutils.CheckMinLength(1)), + resource.TestCheckResourceAttrWith("data.git_commit.test", "author.timestamp", testutils.CheckMinLength(1)), + resource.TestCheckResourceAttrWith("data.git_commit.test", "committer.name", testutils.CheckMinLength(1)), + resource.TestCheckResourceAttrWith("data.git_commit.test", "committer.email", testutils.CheckMinLength(1)), + resource.TestCheckResourceAttrWith("data.git_commit.test", "committer.timestamp", testutils.CheckMinLength(1)), + ), + }, + }, + }) +} + +func TestDataSourceGitCommit_Issue231_MultipleCommits(t *testing.T) { + t.Parallel() + directory, repository := testutils.CreateRepository(t) + testutils.TestConfig(t, repository) + worktree := testutils.GetRepositoryWorktree(t, repository) + fileName1 := "some-file" + fileName2 := "other-file" + testutils.WriteFileInWorktree(t, worktree, fileName1) + testutils.WriteFileInWorktree(t, worktree, fileName2) + testutils.GitAdd(t, worktree, fileName1) + _ = testutils.GitCommit(t, worktree) + testutils.GitAdd(t, worktree, fileName2) // add second file to staging area of second commit + commit2 := testutils.GitCommit(t, worktree) + + resource.UnitTest(t, resource.TestCase{ + ProtoV6ProviderFactories: testutils.ProviderFactories(), + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(` + data "git_commit" "test" { + directory = "%s" + revision = "%s" + } + `, directory, commit2.String()), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.git_commit.test", "directory", directory), + resource.TestCheckResourceAttr("data.git_commit.test", "id", commit2.String()), + resource.TestCheckResourceAttr("data.git_commit.test", "revision", commit2.String()), + resource.TestCheckResourceAttr("data.git_commit.test", "sha1", commit2.String()), + resource.TestCheckResourceAttr("data.git_commit.test", "signature", ""), + resource.TestCheckResourceAttr("data.git_commit.test", "files.#", "1"), + resource.TestCheckResourceAttr("data.git_commit.test", "files.0", "other-file"), + resource.TestCheckResourceAttrWith("data.git_commit.test", "message", testutils.CheckMinLength(1)), + resource.TestCheckResourceAttrWith("data.git_commit.test", "tree_sha1", testutils.CheckMinLength(1)), + resource.TestCheckResourceAttrWith("data.git_commit.test", "author.name", testutils.CheckMinLength(1)), + resource.TestCheckResourceAttrWith("data.git_commit.test", "author.email", testutils.CheckMinLength(1)), + resource.TestCheckResourceAttrWith("data.git_commit.test", "author.timestamp", testutils.CheckMinLength(1)), + resource.TestCheckResourceAttrWith("data.git_commit.test", "committer.name", testutils.CheckMinLength(1)), + resource.TestCheckResourceAttrWith("data.git_commit.test", "committer.email", testutils.CheckMinLength(1)), + resource.TestCheckResourceAttrWith("data.git_commit.test", "committer.timestamp", testutils.CheckMinLength(1)), + ), + }, + }, + }) +} + func TestDataSourceGitCommit_WithHead(t *testing.T) { t.Parallel() directory, repository := testutils.CreateRepository(t) diff --git a/internal/provider/git_commit.go b/internal/provider/git_commit.go index 30f5c50..31de9c5 100644 --- a/internal/provider/git_commit.go +++ b/internal/provider/git_commit.go @@ -12,6 +12,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" + "slices" "time" ) @@ -108,17 +109,40 @@ func objectToSignature(obj *types.Object) *object.Signature { func extractModifiedFiles(commit *object.Commit) []string { fileNames := make([]string, 0) - files, err := commit.Files() - if err != nil { - return fileNames - } - err = files.ForEach(func(file *object.File) error { - fileNames = append(fileNames, file.Name) - return nil - }) - if err != nil { - return fileNames + + if len(commit.ParentHashes) > 0 { + parent, err := commit.Parent(0) + if err != nil { + return fileNames + } + patch, err := parent.Patch(commit) + if err != nil { + return fileNames + } + filePatches := patch.FilePatches() + for _, file := range filePatches { + from, to := file.Files() + if from != nil && !slices.Contains(fileNames, from.Path()) { + fileNames = append(fileNames, from.Path()) + } + if to != nil && !slices.Contains(fileNames, to.Path()) { + fileNames = append(fileNames, to.Path()) + } + } + } else { + files, err := commit.Files() + if err != nil { + return fileNames + } + err = files.ForEach(func(file *object.File) error { + fileNames = append(fileNames, file.Name) + return nil + }) + if err != nil { + return fileNames + } } + return fileNames }