mirror of
https://github.com/abhinav/git-spice.git
synced 2026-08-31 07:47:47 +02:00
internal: merge ioutil, logtest, use external ioutil (#546)
Use the new go.abhg.dev/io/ioutil package instead of internal/ioutil's similar functionality. Merge remaining ioutil and logtest into logutil as it's all log related at this point.
This commit is contained in:
@@ -9,12 +9,12 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.abhg.dev/gs/internal/forge"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
)
|
||||
|
||||
func TestBranchSubmit_listChangeTemplates(t *testing.T) {
|
||||
t.Run("NoTimeout", func(t *testing.T) {
|
||||
log := logtest.New(t)
|
||||
log := logutil.TestLogger(t)
|
||||
ctx := context.Background()
|
||||
tmpl := &forge.ChangeTemplate{}
|
||||
svc := &spiceTemplateServiceStub{
|
||||
@@ -33,7 +33,7 @@ func TestBranchSubmit_listChangeTemplates(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Timeout", func(t *testing.T) {
|
||||
log := logtest.New(t)
|
||||
log := logutil.TestLogger(t)
|
||||
ctx := context.Background()
|
||||
|
||||
svc := &spiceTemplateServiceStub{
|
||||
|
||||
@@ -21,7 +21,6 @@ ignore:
|
||||
- internal/forge/shamhub
|
||||
- internal/forge/forgetest
|
||||
- internal/git/gittest
|
||||
- internal/logtest
|
||||
- internal/mockedit
|
||||
- internal/secret/secrettest
|
||||
- internal/termtest
|
||||
|
||||
@@ -21,6 +21,7 @@ require (
|
||||
github.com/vito/midterm v0.2.1-0.20241224155031-41aafc92c897
|
||||
github.com/zalando/go-keyring v0.2.6
|
||||
gitlab.com/gitlab-org/api/client-go v0.119.0
|
||||
go.abhg.dev/io/ioutil v0.1.0
|
||||
go.abhg.dev/komplete v0.1.0
|
||||
go.abhg.dev/requiredfield v0.3.0
|
||||
go.abhg.dev/testing/stub v0.2.0
|
||||
|
||||
@@ -129,6 +129,8 @@ github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8u
|
||||
github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI=
|
||||
gitlab.com/gitlab-org/api/client-go v0.119.0 h1:YBZyx9XUTtEDBBYtY36cZWz6JmT7om/8HPSk37IS95g=
|
||||
gitlab.com/gitlab-org/api/client-go v0.119.0/go.mod h1:ygHmS3AU3TpvK+AC6DYO1QuAxLlv6yxYK+/Votr/WFQ=
|
||||
go.abhg.dev/io/ioutil v0.1.0 h1:YGGMzh9HT52JYuVWbnr/E5GkYHbL3yRNDjcxFDaUHNk=
|
||||
go.abhg.dev/io/ioutil v0.1.0/go.mod h1:79IIyZVWxNZE8hBxMtubM8zJFPs+2NCqHYfWeH3X6hM=
|
||||
go.abhg.dev/komplete v0.1.0 h1:OE/uazFmWxrYYxttaKri9UpVr/i3J2Iv1vh21mYVom8=
|
||||
go.abhg.dev/komplete v0.1.0/go.mod h1:MYxEW+7RETaNiYbeZv0LOSBmiZ2vfzfk/6m36EC04kc=
|
||||
go.abhg.dev/requiredfield v0.3.0 h1:/fOqPt7t1SktSZVGUNXMg5djO8GasUh+G1ez111UEcs=
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.abhg.dev/gs/internal/forge"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
"go.abhg.dev/testing/stub"
|
||||
)
|
||||
|
||||
@@ -130,7 +130,7 @@ func TestListChangeComments(t *testing.T) {
|
||||
repo, err := newRepository(
|
||||
context.Background(), new(Forge),
|
||||
"owner", "repo",
|
||||
logtest.New(t),
|
||||
logutil.TestLogger(t),
|
||||
githubv4.NewEnterpriseClient(srv.URL, nil),
|
||||
"repoID",
|
||||
)
|
||||
|
||||
@@ -21,8 +21,8 @@ import (
|
||||
"go.abhg.dev/gs/internal/git"
|
||||
"go.abhg.dev/gs/internal/graphqlutil"
|
||||
"go.abhg.dev/gs/internal/httptest"
|
||||
"go.abhg.dev/gs/internal/ioutil"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
"go.abhg.dev/io/ioutil"
|
||||
"golang.org/x/oauth2"
|
||||
"gopkg.in/dnaeon/go-vcr.v4/pkg/cassette"
|
||||
"gopkg.in/dnaeon/go-vcr.v4/pkg/recorder"
|
||||
@@ -95,7 +95,7 @@ func TestIntegration_Repository(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitHubClient(rec.GetDefaultClient())
|
||||
_, err := github.NewRepository(ctx, new(github.Forge), "abhinav", "git-spice", logtest.New(t), ghc, nil)
|
||||
_, err := github.NewRepository(ctx, new(github.Forge), "abhinav", "git-spice", logutil.TestLogger(t), ghc, nil)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ func TestIntegration_Repository_FindChangeByID(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitHubClient(rec.GetDefaultClient())
|
||||
repo, err := github.NewRepository(ctx, new(github.Forge), "abhinav", "git-spice", logtest.New(t), ghc, _gitSpiceRepoID)
|
||||
repo, err := github.NewRepository(ctx, new(github.Forge), "abhinav", "git-spice", logutil.TestLogger(t), ghc, _gitSpiceRepoID)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("found", func(t *testing.T) {
|
||||
@@ -135,7 +135,7 @@ func TestIntegration_Repository_FindChangesByBranch(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitHubClient(rec.GetDefaultClient())
|
||||
repo, err := github.NewRepository(ctx, new(github.Forge), "abhinav", "git-spice", logtest.New(t), ghc, _gitSpiceRepoID)
|
||||
repo, err := github.NewRepository(ctx, new(github.Forge), "abhinav", "git-spice", logutil.TestLogger(t), ghc, _gitSpiceRepoID)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("found", func(t *testing.T) {
|
||||
@@ -168,7 +168,7 @@ func TestIntegration_Repository_ChangesAreMerged(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitHubClient(rec.GetDefaultClient())
|
||||
repo, err := github.NewRepository(ctx, new(github.Forge), "abhinav", "git-spice", logtest.New(t), ghc, _gitSpiceRepoID)
|
||||
repo, err := github.NewRepository(ctx, new(github.Forge), "abhinav", "git-spice", logutil.TestLogger(t), ghc, _gitSpiceRepoID)
|
||||
require.NoError(t, err)
|
||||
|
||||
merged, err := repo.ChangesAreMerged(ctx, []forge.ChangeID{
|
||||
@@ -188,7 +188,7 @@ func TestIntegration_Repository_ListChangeTemplates(t *testing.T) {
|
||||
t.Run("absent", func(t *testing.T) {
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitHubClient(rec.GetDefaultClient())
|
||||
repo, err := github.NewRepository(ctx, new(github.Forge), "abhinav", "git-spice", logtest.New(t), ghc, _gitSpiceRepoID)
|
||||
repo, err := github.NewRepository(ctx, new(github.Forge), "abhinav", "git-spice", logutil.TestLogger(t), ghc, _gitSpiceRepoID)
|
||||
require.NoError(t, err)
|
||||
|
||||
templates, err := repo.ListChangeTemplates(ctx)
|
||||
@@ -199,7 +199,7 @@ func TestIntegration_Repository_ListChangeTemplates(t *testing.T) {
|
||||
t.Run("present", func(t *testing.T) {
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitHubClient(rec.GetDefaultClient())
|
||||
repo, err := github.NewRepository(ctx, new(github.Forge), "golang", "go", logtest.New(t), ghc, nil)
|
||||
repo, err := github.NewRepository(ctx, new(github.Forge), "golang", "go", logutil.TestLogger(t), ghc, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
templates, err := repo.ListChangeTemplates(ctx)
|
||||
@@ -217,7 +217,7 @@ func TestIntegration_Repository_NewChangeMetadata(t *testing.T) {
|
||||
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitHubClient(rec.GetDefaultClient())
|
||||
repo, err := github.NewRepository(ctx, new(github.Forge), "abhinav", "git-spice", logtest.New(t), ghc, _gitSpiceRepoID)
|
||||
repo, err := github.NewRepository(ctx, new(github.Forge), "abhinav", "git-spice", logutil.TestLogger(t), ghc, _gitSpiceRepoID)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("valid", func(t *testing.T) {
|
||||
@@ -254,7 +254,7 @@ func TestIntegration_Repository_SubmitEditChange(t *testing.T) {
|
||||
t.Setenv("GIT_COMMITTER_EMAIL", "bot@example.com")
|
||||
t.Setenv("GIT_COMMITTER_NAME", "gs-test[bot]")
|
||||
|
||||
output := ioutil.TestOutputWriter(t, "[git] ")
|
||||
output := ioutil.TestLogWriter(t, "[git] ")
|
||||
|
||||
t.Logf("Cloning test-repo...")
|
||||
repoDir := t.TempDir()
|
||||
@@ -265,7 +265,7 @@ func TestIntegration_Repository_SubmitEditChange(t *testing.T) {
|
||||
|
||||
var err error
|
||||
gitRepo, err = git.Open(ctx, repoDir, git.OpenOptions{
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
})
|
||||
require.NoError(t, err, "failed to open git repo")
|
||||
|
||||
@@ -309,7 +309,7 @@ func TestIntegration_Repository_SubmitEditChange(t *testing.T) {
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitHubClient(rec.GetDefaultClient())
|
||||
repo, err := github.NewRepository(
|
||||
ctx, new(github.Forge), "abhinav", "test-repo", logtest.New(t), ghc, _testRepoID,
|
||||
ctx, new(github.Forge), "abhinav", "test-repo", logutil.TestLogger(t), ghc, _testRepoID,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -393,7 +393,7 @@ func TestIntegration_Repository_comments(t *testing.T) {
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitHubClient(rec.GetDefaultClient())
|
||||
repo, err := github.NewRepository(
|
||||
ctx, new(github.Forge), "abhinav", "test-repo", logtest.New(t), ghc, _testRepoID,
|
||||
ctx, new(github.Forge), "abhinav", "test-repo", logutil.TestLogger(t), ghc, _testRepoID,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -432,7 +432,7 @@ func TestIntegration_Repository_ListChangeComments_simple(t *testing.T) {
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitHubClient(rec.GetDefaultClient())
|
||||
repo, err := github.NewRepository(
|
||||
ctx, new(github.Forge), "abhinav", "git-spice", logtest.New(t), ghc, _gitSpiceRepoID,
|
||||
ctx, new(github.Forge), "abhinav", "git-spice", logutil.TestLogger(t), ghc, _gitSpiceRepoID,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -476,7 +476,7 @@ func TestIntegration_Repository_ListChangeComments_paginated(t *testing.T) {
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitHubClient(rec.GetDefaultClient())
|
||||
repo, err := github.NewRepository(
|
||||
ctx, new(github.Forge), "abhinav", "test-repo", logtest.New(t), ghc, _testRepoID,
|
||||
ctx, new(github.Forge), "abhinav", "test-repo", logutil.TestLogger(t), ghc, _testRepoID,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -523,7 +523,7 @@ func TestIntegration_Repository_notFoundError(t *testing.T) {
|
||||
client := rec.GetDefaultClient()
|
||||
client.Transport = graphqlutil.WrapTransport(client.Transport)
|
||||
ghc := newGitHubClient(client)
|
||||
_, err := github.NewRepository(ctx, new(github.Forge), "abhinav", "does-not-exist-repo", logtest.New(t), ghc, nil)
|
||||
_, err := github.NewRepository(ctx, new(github.Forge), "abhinav", "does-not-exist-repo", logutil.TestLogger(t), ghc, nil)
|
||||
require.Error(t, err)
|
||||
assert.ErrorIs(t, err, graphqlutil.ErrNotFound)
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
gitlab "gitlab.com/gitlab-org/api/client-go"
|
||||
"go.abhg.dev/gs/internal/forge"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
)
|
||||
|
||||
// SetListChangeCommentsPageSize changes the page size
|
||||
@@ -171,7 +171,7 @@ func TestListChangeComments(t *testing.T) {
|
||||
repo, err := newRepository(
|
||||
context.Background(), new(Forge),
|
||||
"owner", "repo",
|
||||
logtest.New(t),
|
||||
logutil.TestLogger(t),
|
||||
client,
|
||||
&repoID,
|
||||
)
|
||||
|
||||
@@ -20,8 +20,8 @@ import (
|
||||
"go.abhg.dev/gs/internal/forge/gitlab"
|
||||
"go.abhg.dev/gs/internal/git"
|
||||
"go.abhg.dev/gs/internal/httptest"
|
||||
"go.abhg.dev/gs/internal/ioutil"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
"go.abhg.dev/io/ioutil"
|
||||
"gopkg.in/dnaeon/go-vcr.v4/pkg/cassette"
|
||||
"gopkg.in/dnaeon/go-vcr.v4/pkg/recorder"
|
||||
)
|
||||
@@ -99,7 +99,7 @@ func TestIntegration_Repository(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitLabClient(rec.GetDefaultClient())
|
||||
_, err := gitlab.NewRepository(ctx, new(gitlab.Forge), "abg", "test-repo", logtest.New(t), ghc, nil)
|
||||
_, err := gitlab.NewRepository(ctx, new(gitlab.Forge), "abg", "test-repo", logutil.TestLogger(t), ghc, nil)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ func TestIntegration_Repository_FindChangeByID(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitLabClient(rec.GetDefaultClient())
|
||||
repo, err := gitlab.NewRepository(ctx, new(gitlab.Forge), "abg", "test-repo", logtest.New(t), ghc, _testRepoID)
|
||||
repo, err := gitlab.NewRepository(ctx, new(gitlab.Forge), "abg", "test-repo", logutil.TestLogger(t), ghc, _testRepoID)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("found", func(t *testing.T) {
|
||||
@@ -138,7 +138,7 @@ func TestIntegration_Repository_FindChangesByBranch(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitLabClient(rec.GetDefaultClient())
|
||||
repo, err := gitlab.NewRepository(ctx, new(gitlab.Forge), "abg", "test-repo", logtest.New(t), ghc, _testRepoID)
|
||||
repo, err := gitlab.NewRepository(ctx, new(gitlab.Forge), "abg", "test-repo", logutil.TestLogger(t), ghc, _testRepoID)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("found", func(t *testing.T) {
|
||||
@@ -170,7 +170,7 @@ func TestIntegration_Repository_ChangesAreMerged(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitLabClient(rec.GetDefaultClient())
|
||||
repo, err := gitlab.NewRepository(ctx, new(gitlab.Forge), "abg", "test-repo", logtest.New(t), ghc, _testRepoID)
|
||||
repo, err := gitlab.NewRepository(ctx, new(gitlab.Forge), "abg", "test-repo", logutil.TestLogger(t), ghc, _testRepoID)
|
||||
require.NoError(t, err)
|
||||
|
||||
merged, err := repo.ChangesAreMerged(ctx, []forge.ChangeID{
|
||||
@@ -188,7 +188,7 @@ func TestIntegration_Repository_ListChangeTemplates(t *testing.T) {
|
||||
t.Run("absent", func(t *testing.T) {
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitLabClient(rec.GetDefaultClient())
|
||||
repo, err := gitlab.NewRepository(ctx, new(gitlab.Forge), "abg", "test-repo", logtest.New(t), ghc, _testRepoID)
|
||||
repo, err := gitlab.NewRepository(ctx, new(gitlab.Forge), "abg", "test-repo", logutil.TestLogger(t), ghc, _testRepoID)
|
||||
require.NoError(t, err)
|
||||
|
||||
templates, err := repo.ListChangeTemplates(ctx)
|
||||
@@ -199,7 +199,7 @@ func TestIntegration_Repository_ListChangeTemplates(t *testing.T) {
|
||||
t.Run("present", func(t *testing.T) {
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitLabClient(rec.GetDefaultClient())
|
||||
repo, err := gitlab.NewRepository(ctx, new(gitlab.Forge), "gitlab-org", "cli", logtest.New(t), ghc, nil)
|
||||
repo, err := gitlab.NewRepository(ctx, new(gitlab.Forge), "gitlab-org", "cli", logutil.TestLogger(t), ghc, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
templates, err := repo.ListChangeTemplates(ctx)
|
||||
@@ -217,7 +217,7 @@ func TestIntegration_Repository_NewChangeMetadata(t *testing.T) {
|
||||
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitLabClient(rec.GetDefaultClient())
|
||||
repo, err := gitlab.NewRepository(ctx, new(gitlab.Forge), "abg", "test-repo", logtest.New(t), ghc, _testRepoID)
|
||||
repo, err := gitlab.NewRepository(ctx, new(gitlab.Forge), "abg", "test-repo", logutil.TestLogger(t), ghc, _testRepoID)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("valid", func(t *testing.T) {
|
||||
@@ -252,7 +252,7 @@ func TestIntegration_Repository_SubmitEditChange(t *testing.T) {
|
||||
t.Setenv("GIT_COMMITTER_EMAIL", "bot@example.com")
|
||||
t.Setenv("GIT_COMMITTER_NAME", "gs-test[bot]")
|
||||
|
||||
output := ioutil.TestOutputWriter(t, "[git] ")
|
||||
output := ioutil.TestLogWriter(t, "[git] ")
|
||||
|
||||
t.Logf("Cloning test-repo...")
|
||||
repoDir := t.TempDir()
|
||||
@@ -263,7 +263,7 @@ func TestIntegration_Repository_SubmitEditChange(t *testing.T) {
|
||||
|
||||
var err error
|
||||
gitRepo, err = git.Open(ctx, repoDir, git.OpenOptions{
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
})
|
||||
require.NoError(t, err, "failed to open git repo")
|
||||
|
||||
@@ -307,7 +307,7 @@ func TestIntegration_Repository_SubmitEditChange(t *testing.T) {
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitLabClient(rec.GetDefaultClient())
|
||||
repo, err := gitlab.NewRepository(
|
||||
ctx, new(gitlab.Forge), "abg", "test-repo", logtest.New(t), ghc, _testRepoID,
|
||||
ctx, new(gitlab.Forge), "abg", "test-repo", logutil.TestLogger(t), ghc, _testRepoID,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -391,7 +391,7 @@ func TestIntegration_Repository_comments(t *testing.T) {
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitLabClient(rec.GetDefaultClient())
|
||||
repo, err := gitlab.NewRepository(
|
||||
ctx, new(gitlab.Forge), "abg", "test-repo", logtest.New(t), ghc, _testRepoID,
|
||||
ctx, new(gitlab.Forge), "abg", "test-repo", logutil.TestLogger(t), ghc, _testRepoID,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -428,7 +428,7 @@ func TestIntegration_Repository_ListChangeComments_simple(t *testing.T) {
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitLabClient(rec.GetDefaultClient())
|
||||
repo, err := gitlab.NewRepository(
|
||||
ctx, new(gitlab.Forge), "abg", "test-repo", logtest.New(t), ghc, _testRepoID,
|
||||
ctx, new(gitlab.Forge), "abg", "test-repo", logutil.TestLogger(t), ghc, _testRepoID,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -472,7 +472,7 @@ func TestIntegration_Repository_ListChangeComments_paginated(t *testing.T) {
|
||||
rec := newRecorder(t, t.Name())
|
||||
ghc := newGitLabClient(rec.GetDefaultClient())
|
||||
repo, err := gitlab.NewRepository(
|
||||
ctx, new(gitlab.Forge), "abg", "test-repo", logtest.New(t), ghc, _testRepoID,
|
||||
ctx, new(gitlab.Forge), "abg", "test-repo", logutil.TestLogger(t), ghc, _testRepoID,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -518,7 +518,7 @@ func TestIntegration_Repository_notFoundError(t *testing.T) {
|
||||
rec := newRecorder(t, t.Name())
|
||||
client := rec.GetDefaultClient()
|
||||
ghc := newGitLabClient(client)
|
||||
_, err := gitlab.NewRepository(ctx, new(gitlab.Forge), "abg", "does-not-exist-repo", logtest.New(t), ghc, nil)
|
||||
_, err := gitlab.NewRepository(ctx, new(gitlab.Forge), "abg", "does-not-exist-repo", logutil.TestLogger(t), ghc, nil)
|
||||
require.Error(t, err)
|
||||
assert.ErrorContains(t, err, "404 Not Found")
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"go.abhg.dev/gs/internal/forge"
|
||||
"go.abhg.dev/gs/internal/ioutil"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
)
|
||||
|
||||
// ListChanges reports all changes known to the forge.
|
||||
@@ -136,7 +136,7 @@ type ChangeBranch struct {
|
||||
}
|
||||
|
||||
func (sh *ShamHub) toChangeBranch(owner, repo, ref string) (*ChangeBranch, error) {
|
||||
logw, flush := ioutil.LogWriter(sh.log, log.DebugLevel)
|
||||
logw, flush := logutil.Writer(sh.log, log.DebugLevel)
|
||||
defer flush()
|
||||
|
||||
cmd := exec.Command(sh.gitExe, "rev-parse", ref)
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/rogpeppe/go-internal/testscript"
|
||||
"go.abhg.dev/gs/internal/ioutil"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
"go.abhg.dev/io/ioutil"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
@@ -58,7 +58,7 @@ func (c *Cmd) Run(ts *testscript.TestScript, neg bool, args []string) {
|
||||
|
||||
t := scriptState.t
|
||||
sh, err := New(Config{
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
})
|
||||
if err != nil {
|
||||
ts.Fatalf("create ShamHub: %s", err)
|
||||
@@ -126,7 +126,7 @@ func (c *Cmd) Run(ts *testscript.TestScript, neg bool, args []string) {
|
||||
ts.Fatalf("ShamHub not initialized")
|
||||
}
|
||||
|
||||
logw, closeLogw := ioutil.LogfWriter(ts.Logf, "shamhub merge: ")
|
||||
logw, closeLogw := ioutil.PrintfWriter(ts.Logf, "shamhub merge: ")
|
||||
ts.Defer(closeLogw)
|
||||
|
||||
flag := flag.NewFlagSet("shamhub merge", flag.ContinueOnError)
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"go.abhg.dev/gs/internal/forge"
|
||||
"go.abhg.dev/gs/internal/ioutil"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
)
|
||||
|
||||
type areMergedRequest struct {
|
||||
@@ -162,7 +162,7 @@ func (sh *ShamHub) MergeChange(req MergeChangeRequest) error {
|
||||
//
|
||||
// This requires at least Git 2.38.
|
||||
tree, err := func() (string, error) {
|
||||
logw, flush := ioutil.LogWriter(sh.log, log.DebugLevel)
|
||||
logw, flush := logutil.Writer(sh.log, log.DebugLevel)
|
||||
defer flush()
|
||||
|
||||
cmd := exec.Command(sh.gitExe, "merge-tree", "--write-tree", sh.changes[changeIdx].Base, sh.changes[changeIdx].Head)
|
||||
@@ -180,7 +180,7 @@ func (sh *ShamHub) MergeChange(req MergeChangeRequest) error {
|
||||
}
|
||||
|
||||
commit, err := func() (string, error) {
|
||||
logw, flush := ioutil.LogWriter(sh.log, log.DebugLevel)
|
||||
logw, flush := logutil.Writer(sh.log, log.DebugLevel)
|
||||
defer flush()
|
||||
|
||||
change := sh.changes[changeIdx]
|
||||
@@ -215,7 +215,7 @@ func (sh *ShamHub) MergeChange(req MergeChangeRequest) error {
|
||||
|
||||
// Update the ref to point to the new commit.
|
||||
err = func() error {
|
||||
logw, flush := ioutil.LogWriter(sh.log, log.DebugLevel)
|
||||
logw, flush := logutil.Writer(sh.log, log.DebugLevel)
|
||||
defer flush()
|
||||
|
||||
ref := fmt.Sprintf("refs/heads/%s", sh.changes[changeIdx].Base)
|
||||
@@ -234,7 +234,7 @@ func (sh *ShamHub) MergeChange(req MergeChangeRequest) error {
|
||||
|
||||
if req.DeleteBranch {
|
||||
err := func() error {
|
||||
logw, flush := ioutil.LogWriter(sh.log, log.DebugLevel)
|
||||
logw, flush := logutil.Writer(sh.log, log.DebugLevel)
|
||||
defer flush()
|
||||
|
||||
cmd := exec.Command(sh.gitExe, "branch", "-D", sh.changes[changeIdx].Head)
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"go.abhg.dev/gs/internal/forge"
|
||||
"go.abhg.dev/gs/internal/ioutil"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
"go.abhg.dev/gs/internal/must"
|
||||
)
|
||||
|
||||
@@ -27,7 +27,7 @@ func (sh *ShamHub) NewRepository(owner, repo string) (string, error) {
|
||||
return "", fmt.Errorf("create repository: %w", err)
|
||||
}
|
||||
|
||||
logw, flush := ioutil.LogWriter(sh.log, log.DebugLevel)
|
||||
logw, flush := logutil.Writer(sh.log, log.DebugLevel)
|
||||
defer flush()
|
||||
|
||||
initCmd := exec.Command(sh.gitExe, "init", "--bare", "--initial-branch=main")
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"go.abhg.dev/gs/internal/forge"
|
||||
"go.abhg.dev/gs/internal/ioutil"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
)
|
||||
|
||||
type submitChangeRequest struct {
|
||||
@@ -103,7 +103,7 @@ func (f *forgeRepository) SubmitChange(ctx context.Context, r forge.SubmitChange
|
||||
}
|
||||
|
||||
func (sh *ShamHub) branchRefExists(ctx context.Context, owner, repo, branch string) bool {
|
||||
logw, flush := ioutil.LogWriter(sh.log, log.DebugLevel)
|
||||
logw, flush := logutil.Writer(sh.log, log.DebugLevel)
|
||||
defer flush()
|
||||
|
||||
cmd := exec.CommandContext(ctx, sh.gitExe,
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"go.abhg.dev/gs/internal/forge"
|
||||
"go.abhg.dev/gs/internal/ioutil"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
)
|
||||
|
||||
var _changeTemplatePaths = []string{
|
||||
@@ -43,7 +43,7 @@ func (sh *ShamHub) handleChangeTemplate(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
// If the repository has a .shamhub/CHANGE_TEMPLATE.md file,
|
||||
// that's the template to use.
|
||||
logw, flush := ioutil.LogWriter(sh.log, log.DebugLevel)
|
||||
logw, flush := logutil.Writer(sh.log, log.DebugLevel)
|
||||
defer flush()
|
||||
|
||||
templatePaths := make(map[string]struct{})
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.abhg.dev/gs/internal/git"
|
||||
"go.abhg.dev/gs/internal/git/gittest"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
"go.abhg.dev/gs/internal/text"
|
||||
)
|
||||
|
||||
@@ -45,7 +45,7 @@ func TestIntegrationBranches(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
repo, err := git.Open(ctx, fixture.Dir(), git.OpenOptions{
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -191,7 +191,7 @@ func TestIntegrationLocalBranchesWorktrees(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
repo, err := git.Open(ctx,
|
||||
filepath.Join(fixture.Dir(), "repo"),
|
||||
git.OpenOptions{Log: logtest.New(t)},
|
||||
git.OpenOptions{Log: logutil.TestLogger(t)},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -245,7 +245,7 @@ func TestIntegrationRemoteBranches(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
repo, err := git.Open(ctx,
|
||||
filepath.Join(fixture.Dir(), "clone"),
|
||||
git.OpenOptions{Log: logtest.New(t)},
|
||||
git.OpenOptions{Log: logutil.TestLogger(t)},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"go.abhg.dev/gs/internal/ioutil"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
)
|
||||
|
||||
// execer controls actual execution of Git commands.
|
||||
@@ -187,7 +187,7 @@ func stderrWriter(cmd string, logger *log.Logger) (w io.Writer, wrap func(error)
|
||||
// If logging is enabled, return an io.Writer
|
||||
// that writes to the logger.
|
||||
cmdLog := logger.WithPrefix(cmd)
|
||||
w, flush := ioutil.LogWriter(cmdLog, log.DebugLevel)
|
||||
w, flush := logutil.Writer(cmdLog, log.DebugLevel)
|
||||
return w, func(err error) error {
|
||||
flush()
|
||||
return err
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
"go.abhg.dev/gs/internal/sliceutil"
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
@@ -143,7 +143,7 @@ func TestConfigListRegexp(t *testing.T) {
|
||||
|
||||
cfg := NewConfig(ConfigOptions{
|
||||
Dir: t.TempDir(),
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
exec: execer,
|
||||
})
|
||||
|
||||
@@ -228,7 +228,7 @@ func TestIntegrationConfigListRegexp(t *testing.T) {
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
log := logtest.New(t)
|
||||
log := logutil.TestLogger(t)
|
||||
for _, set := range tt.sets {
|
||||
args := append([]string{"config", "--global"}, set...)
|
||||
err := newGitCmd(ctx, log, args...).
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.abhg.dev/gs/internal/git"
|
||||
"go.abhg.dev/gs/internal/git/gittest"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
"go.abhg.dev/gs/internal/text"
|
||||
)
|
||||
|
||||
@@ -54,7 +54,7 @@ func TestIntegrationCommitListing(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
repo, err := git.Open(ctx, fixture.Dir(), git.OpenOptions{
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.abhg.dev/gs/internal/git"
|
||||
"go.abhg.dev/gs/internal/git/gittest"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
"go.abhg.dev/gs/internal/mockedit"
|
||||
"go.abhg.dev/gs/internal/text"
|
||||
)
|
||||
@@ -48,7 +48,7 @@ func TestRebase_deliberateInterrupt(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
repo, err := git.Open(ctx, fixture.Dir(), git.OpenOptions{
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -133,7 +133,7 @@ func TestRebase_unexpectedInterrupt(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
repo, err := git.Open(ctx, fixture.Dir(), git.OpenOptions{
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
)
|
||||
|
||||
func NewTestRepository(t testing.TB, dir string, execer execer) *Repository {
|
||||
@@ -21,7 +21,7 @@ func NewTestRepository(t testing.TB, dir string, execer execer) *Repository {
|
||||
}
|
||||
}
|
||||
|
||||
return newRepository(dir, gitDir, logtest.New(t), execer)
|
||||
return newRepository(dir, gitDir, logutil.TestLogger(t), execer)
|
||||
}
|
||||
|
||||
func TestExtraConfig_Args(t *testing.T) {
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.abhg.dev/gs/internal/git"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
)
|
||||
|
||||
func TestParseMode(t *testing.T) {
|
||||
@@ -35,7 +35,7 @@ func TestIntegrationListTreeAbsent(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
repo, err := git.Init(ctx, t.TempDir(), git.InitOptions{
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -48,7 +48,7 @@ func TestIntegrationMakeTree(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
repo, err := git.Init(ctx, t.TempDir(), git.InitOptions{
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -94,7 +94,7 @@ func TestIntegrationUpdateTree(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
repo, err := git.Init(ctx, t.TempDir(), git.InitOptions{
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
// Package ioutil provides I/O utilities.
|
||||
package ioutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
)
|
||||
|
||||
// LogWriter builds and returns an io.Writer that
|
||||
// writes messages to the given logger.
|
||||
// If the logger is nil, a no-op writer is returned.
|
||||
//
|
||||
// If prefix is non-empty, it is prepended to each message.
|
||||
// The done function must be called when the writer is no longer needed.
|
||||
// It will flush any buffered text to the logger.
|
||||
//
|
||||
// The returned writer is not thread-safe.
|
||||
func LogWriter(log *log.Logger, lvl log.Level) (w io.Writer, done func()) {
|
||||
if log == nil {
|
||||
return io.Discard, func() {}
|
||||
}
|
||||
|
||||
w, flush := LogfWriter(func(msg string, args ...any) {
|
||||
log.Logf(lvl, msg, args...)
|
||||
}, "")
|
||||
return w, flush
|
||||
}
|
||||
|
||||
// TestOutput allows writing to the test log.
|
||||
type TestOutput interface {
|
||||
Logf(format string, args ...any)
|
||||
Cleanup(f func())
|
||||
}
|
||||
|
||||
// TestOutputWriter builds and returns an io.Writer that
|
||||
// writes messages to the given testing.TB.
|
||||
// The returned writer is not thread-safe.
|
||||
func TestOutputWriter(t TestOutput, prefix string) (w io.Writer) {
|
||||
w, flush := LogfWriter(t.Logf, prefix)
|
||||
t.Cleanup(flush)
|
||||
return w
|
||||
}
|
||||
|
||||
// printfWriter is an io.Writer that writes to a log.Logger.
|
||||
type printfWriter struct {
|
||||
// printf implementation should add a newline at the end.
|
||||
printf func(string, ...any)
|
||||
prefix string
|
||||
buff bytes.Buffer
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
var _ io.Writer = (*printfWriter)(nil)
|
||||
|
||||
// LogfWriter builds an io.Writer that writes messages
|
||||
// to the given logf-style function.
|
||||
//
|
||||
// The function is expected to always add a newline to the end of messages.
|
||||
func LogfWriter(printf func(string, ...any), prefix string) (io.Writer, func()) {
|
||||
w := &printfWriter{
|
||||
printf: printf,
|
||||
prefix: prefix,
|
||||
}
|
||||
return w, w.flush
|
||||
}
|
||||
|
||||
var _newline = []byte{'\n'}
|
||||
|
||||
func (w *printfWriter) Write(bs []byte) (int, error) {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
|
||||
total := len(bs)
|
||||
for len(bs) > 0 {
|
||||
var (
|
||||
line []byte
|
||||
ok bool
|
||||
)
|
||||
line, bs, ok = bytes.Cut(bs, _newline)
|
||||
if !ok {
|
||||
// No newline. Buffer and wait for more.
|
||||
w.buff.Write(line)
|
||||
break
|
||||
}
|
||||
|
||||
if w.buff.Len() == 0 {
|
||||
// No prior partial write. Flush.
|
||||
w.printf("%s%s", w.prefix, line)
|
||||
continue
|
||||
}
|
||||
|
||||
// Flush prior partial write.
|
||||
w.buff.Write(line)
|
||||
w.printf("%s%s", w.prefix, w.buff.Bytes())
|
||||
w.buff.Reset()
|
||||
}
|
||||
return total, nil
|
||||
}
|
||||
|
||||
// flush flushes buffered text, even if it doesn't end with a newline.
|
||||
func (w *printfWriter) flush() {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
|
||||
if w.buff.Len() > 0 {
|
||||
w.printf("%s%s", w.prefix, w.buff.Bytes())
|
||||
w.buff.Reset()
|
||||
}
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
package ioutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"pgregory.net/rapid"
|
||||
)
|
||||
|
||||
func TestLogWriter(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
logger := log.New(&buf)
|
||||
writer, done := LogWriter(logger, log.InfoLevel)
|
||||
|
||||
_, err := fmt.Fprint(writer, "hello world")
|
||||
require.NoError(t, err)
|
||||
done()
|
||||
|
||||
assert.Equal(t, "INFO hello world\n", buf.String())
|
||||
}
|
||||
|
||||
func TestLogWriter_nil(t *testing.T) {
|
||||
writer, done := LogWriter(nil, log.InfoLevel)
|
||||
|
||||
_, err := fmt.Fprint(writer, "hello world")
|
||||
require.NoError(t, err)
|
||||
done()
|
||||
}
|
||||
|
||||
func TestTestOutputWriter(t *testing.T) {
|
||||
var out testOutputStub
|
||||
writer := TestOutputWriter(&out, "prefix: ")
|
||||
|
||||
fmt.Fprint(writer, "hello world")
|
||||
out.cleanup()
|
||||
|
||||
assert.Equal(t, []string{"prefix: hello world"}, out.logs)
|
||||
}
|
||||
|
||||
type testOutputStub struct {
|
||||
logs []string
|
||||
cleanup func()
|
||||
}
|
||||
|
||||
func (t *testOutputStub) Logf(format string, args ...any) {
|
||||
t.logs = append(t.logs, fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
func (t *testOutputStub) Cleanup(f func()) {
|
||||
old := t.cleanup
|
||||
t.cleanup = func() {
|
||||
f()
|
||||
if old != nil {
|
||||
old()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintfWriter(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
prefix string
|
||||
writes []string
|
||||
want []string
|
||||
}{
|
||||
{desc: "empty"},
|
||||
{
|
||||
desc: "single line",
|
||||
writes: []string{"hello world"},
|
||||
want: []string{"hello world"},
|
||||
},
|
||||
{
|
||||
desc: "single line/prefix",
|
||||
prefix: "prefix: ",
|
||||
writes: []string{"hello world"},
|
||||
want: []string{"prefix: hello world"},
|
||||
},
|
||||
{
|
||||
desc: "single line/newline",
|
||||
writes: []string{"hello world\n"},
|
||||
want: []string{"hello world"},
|
||||
},
|
||||
{
|
||||
desc: "single line/newline and prefix",
|
||||
prefix: "prefix: ",
|
||||
writes: []string{"hello world\n"},
|
||||
want: []string{"prefix: hello world"},
|
||||
},
|
||||
{
|
||||
desc: "multi line",
|
||||
writes: []string{"foo\n", "bar\n"},
|
||||
want: []string{"foo", "bar"},
|
||||
},
|
||||
{
|
||||
desc: "newline with separate write",
|
||||
writes: []string{"foo", "\n", "bar\n"},
|
||||
want: []string{"foo", "bar"},
|
||||
},
|
||||
{
|
||||
desc: "line across many writes",
|
||||
writes: []string{"f", "oo\nb", "ar\nb", "az\n"},
|
||||
want: []string{"foo", "bar", "baz"},
|
||||
},
|
||||
{
|
||||
desc: "empty line",
|
||||
writes: []string{
|
||||
"foo\n",
|
||||
"\n",
|
||||
"bar\n",
|
||||
},
|
||||
want: []string{"foo", "", "bar"},
|
||||
},
|
||||
{
|
||||
desc: "empty line/prefix",
|
||||
prefix: "prefix: ",
|
||||
writes: []string{
|
||||
"foo\n",
|
||||
"\n",
|
||||
"bar\n",
|
||||
},
|
||||
want: []string{"prefix: foo", "prefix: ", "prefix: bar"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
var got []string
|
||||
w, flush := LogfWriter(
|
||||
func(format string, args ...any) {
|
||||
got = append(got, fmt.Sprintf(format, args...))
|
||||
},
|
||||
tt.prefix,
|
||||
)
|
||||
|
||||
for _, s := range tt.writes {
|
||||
fmt.Fprint(w, s)
|
||||
}
|
||||
flush()
|
||||
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintfWriterRapid(t *testing.T) {
|
||||
rapid.Check(t, testPrintfWriterRapid)
|
||||
}
|
||||
|
||||
func FuzzPrintfWriterRapid(f *testing.F) {
|
||||
f.Fuzz(rapid.MakeFuzz(testPrintfWriterRapid))
|
||||
}
|
||||
|
||||
func testPrintfWriterRapid(t *rapid.T) {
|
||||
var gotBuff bytes.Buffer
|
||||
w, flush := LogfWriter(func(format string, args ...any) {
|
||||
_, err := fmt.Fprintf(&gotBuff, format+"\n", args...)
|
||||
assert.NoError(t, err)
|
||||
}, "")
|
||||
|
||||
var wantBuff bytes.Buffer
|
||||
chunks := rapid.SliceOf(rapid.SliceOf(rapid.Byte())).Draw(t, "chunks")
|
||||
for _, chunk := range chunks {
|
||||
wantBuff.Write(chunk)
|
||||
_, err := w.Write(chunk)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
flush()
|
||||
|
||||
got := strings.TrimSuffix(gotBuff.String(), "\n")
|
||||
want := strings.TrimSuffix(wantBuff.String(), "\n")
|
||||
|
||||
assert.Equal(t, want, got)
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
// Package logtest provides a log.Logger for testing.
|
||||
package logtest
|
||||
|
||||
import (
|
||||
"github.com/charmbracelet/log"
|
||||
"go.abhg.dev/gs/internal/ioutil"
|
||||
)
|
||||
|
||||
// New builds a logger that writes messages
|
||||
// to the given testing.TB.
|
||||
func New(t ioutil.TestOutput) *log.Logger {
|
||||
return log.New(ioutil.TestOutputWriter(t, ""))
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// Package logutil provides utilities for logging.
|
||||
package logutil
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"go.abhg.dev/io/ioutil"
|
||||
)
|
||||
|
||||
// Writer builds and returns an io.Writer that
|
||||
// writes messages to the given logger.
|
||||
// If the logger is nil, a no-op writer is returned.
|
||||
//
|
||||
// If prefix is non-empty, it is prepended to each message.
|
||||
// The done function must be called when the writer is no longer needed.
|
||||
// It will flush any buffered text to the logger.
|
||||
//
|
||||
// The returned writer is not thread-safe.
|
||||
func Writer(log *log.Logger, lvl log.Level) (w io.Writer, done func()) {
|
||||
if log == nil {
|
||||
return io.Discard, func() {}
|
||||
}
|
||||
|
||||
w, flush := ioutil.PrintfWriter(func(msg string, args ...any) {
|
||||
log.Logf(lvl, msg, args...)
|
||||
}, "")
|
||||
return w, flush
|
||||
}
|
||||
|
||||
// TestLogger builds a logger that writes messages
|
||||
// to the given testing.TB.
|
||||
func TestLogger(t ioutil.TestLogger) *log.Logger {
|
||||
return log.New(ioutil.TestLogWriter(t, ""))
|
||||
}
|
||||
@@ -1,16 +1,39 @@
|
||||
package logtest
|
||||
package logutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestLogger(t *testing.T) {
|
||||
func TestLogWriter(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
logger := log.New(&buf)
|
||||
writer, done := Writer(logger, log.InfoLevel)
|
||||
|
||||
_, err := fmt.Fprint(writer, "hello world")
|
||||
require.NoError(t, err)
|
||||
done()
|
||||
|
||||
assert.Equal(t, "INFO hello world\n", buf.String())
|
||||
}
|
||||
|
||||
func TestLogWriter_nil(t *testing.T) {
|
||||
writer, done := Writer(nil, log.InfoLevel)
|
||||
|
||||
_, err := fmt.Fprint(writer, "hello world")
|
||||
require.NoError(t, err)
|
||||
done()
|
||||
}
|
||||
|
||||
func TestTestLogger(t *testing.T) {
|
||||
var stub testOutputStub
|
||||
logger := New(&stub)
|
||||
logger := TestLogger(&stub)
|
||||
|
||||
logger.Infof("Hello, %s!", "world")
|
||||
logger.Error("Sadness", "err", errors.New("oh no"))
|
||||
@@ -7,14 +7,14 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
)
|
||||
|
||||
func TestInsecureStashSaveEmptyDeletesFile(t *testing.T) {
|
||||
file := filepath.Join(t.TempDir(), "secrets.json")
|
||||
stash := InsecureStash{
|
||||
Path: file,
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
}
|
||||
|
||||
// Delete non-existent secret.
|
||||
@@ -38,7 +38,7 @@ func TestInsecureCannotReadOrWrite(t *testing.T) {
|
||||
|
||||
stash := InsecureStash{
|
||||
Path: file,
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
}
|
||||
|
||||
t.Run("Save", func(t *testing.T) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/zalando/go-keyring"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
"go.abhg.dev/gs/internal/secret"
|
||||
)
|
||||
|
||||
@@ -35,7 +35,7 @@ func TestStash(t *testing.T) {
|
||||
file := filepath.Join(t.TempDir(), "secrets.json")
|
||||
stash := secret.InsecureStash{
|
||||
Path: file,
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
}
|
||||
testStash(t, &stash)
|
||||
})
|
||||
@@ -44,7 +44,7 @@ func TestStash(t *testing.T) {
|
||||
file := filepath.Join(t.TempDir(), "nested", "dir", "secrets.json")
|
||||
stash := secret.InsecureStash{
|
||||
Path: file,
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
}
|
||||
testStash(t, &stash)
|
||||
})
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"go.abhg.dev/gs/internal/forge"
|
||||
"go.abhg.dev/gs/internal/forge/shamhub"
|
||||
"go.abhg.dev/gs/internal/git"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
"go.abhg.dev/gs/internal/spice/state"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
@@ -46,7 +46,7 @@ func TestService_LookupBranch_changeAssociation(t *testing.T) {
|
||||
t.Cleanup(shamhubServer.Close)
|
||||
|
||||
shamhubForge := &shamhub.Forge{
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
Options: shamhub.Options{
|
||||
URL: shamhubServer.URL,
|
||||
APIURL: shamhubServer.URL,
|
||||
@@ -70,7 +70,7 @@ func TestService_LookupBranch_changeAssociation(t *testing.T) {
|
||||
Return(git.Hash("def123"), nil).
|
||||
AnyTimes()
|
||||
|
||||
svc := NewService(ctx, mockRepo, mockStore, logtest.New(t))
|
||||
svc := NewService(ctx, mockRepo, mockStore, logutil.TestLogger(t))
|
||||
|
||||
// We should still be able to resolve metadata
|
||||
// for known forges.
|
||||
@@ -138,7 +138,7 @@ func TestService_LookupBranch_changeAssociation(t *testing.T) {
|
||||
ChangeForge: shamhubForge.ID(),
|
||||
}, nil)
|
||||
|
||||
svc := NewService(ctx, mockRepo, mockStore, logtest.New(t))
|
||||
svc := NewService(ctx, mockRepo, mockStore, logutil.TestLogger(t))
|
||||
resp, err := svc.LookupBranch(ctx, "feature")
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.abhg.dev/gs/internal/git"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
"go.abhg.dev/gs/internal/spice"
|
||||
"go.abhg.dev/gs/internal/text"
|
||||
)
|
||||
@@ -193,7 +193,7 @@ func TestIntegrationConfig_loadFromGit(t *testing.T) {
|
||||
// Read configuration
|
||||
ctx := context.Background()
|
||||
gitCfg := git.NewConfig(git.ConfigOptions{
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
Dir: home,
|
||||
Env: []string{
|
||||
"HOME=" + home,
|
||||
@@ -202,7 +202,7 @@ func TestIntegrationConfig_loadFromGit(t *testing.T) {
|
||||
},
|
||||
})
|
||||
spicecfg, err := spice.LoadConfig(ctx, gitCfg, spice.ConfigOptions{
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
})
|
||||
require.NoError(t, err, "load configuration")
|
||||
|
||||
|
||||
@@ -8,12 +8,12 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.abhg.dev/gs/internal/git"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
func TestUnusedBranchName(t *testing.T) {
|
||||
log := logtest.New(t)
|
||||
log := logutil.TestLogger(t)
|
||||
|
||||
type listRemoteRefsCall struct {
|
||||
want []string
|
||||
@@ -95,7 +95,7 @@ func TestUnusedBranchName(t *testing.T) {
|
||||
func TestUnusedBranchName_listError(t *testing.T) {
|
||||
mockCtrl := gomock.NewController(t)
|
||||
repo := NewMockGitRepository(mockCtrl)
|
||||
svc := NewTestService(repo, NewMockStore(mockCtrl), nil, logtest.New(t))
|
||||
svc := NewTestService(repo, NewMockStore(mockCtrl), nil, logutil.TestLogger(t))
|
||||
|
||||
repo.EXPECT().
|
||||
ListRemoteRefs(gomock.Any(), "origin", gomock.Any()).
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.abhg.dev/gs/internal/git"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
)
|
||||
|
||||
func TestStorageBackend(t *testing.T) {
|
||||
@@ -20,7 +20,7 @@ func TestStorageBackend(t *testing.T) {
|
||||
t.Run("Git", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
repo, err := git.Init(ctx, t.TempDir(), git.InitOptions{
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -29,7 +29,7 @@ func TestStorageBackend(t *testing.T) {
|
||||
Ref: "refs/heads/test",
|
||||
AuthorName: "Test",
|
||||
AuthorEmail: "test@example.com",
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -7,13 +7,13 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.abhg.dev/gs/internal/git"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
)
|
||||
|
||||
func TestGitBackendUpdateNoChanges(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
repo, err := git.Init(ctx, t.TempDir(), git.InitOptions{
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -22,7 +22,7 @@ func TestGitBackendUpdateNoChanges(t *testing.T) {
|
||||
Ref: "refs/data",
|
||||
AuthorName: "Test Author",
|
||||
AuthorEmail: "test@example.com",
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
})
|
||||
|
||||
db := NewDB(backend)
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
"go.abhg.dev/gs/internal/spice/state"
|
||||
"go.abhg.dev/gs/internal/spice/state/storage"
|
||||
)
|
||||
@@ -22,7 +22,7 @@ func TestStore(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
store, err := state.OpenStore(ctx, db, logtest.New(t))
|
||||
store, err := state.OpenStore(ctx, db, logutil.TestLogger(t))
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"go.abhg.dev/gs/internal/forge/forgetest"
|
||||
"go.abhg.dev/gs/internal/git"
|
||||
"go.abhg.dev/gs/internal/git/gittest"
|
||||
"go.abhg.dev/gs/internal/logtest"
|
||||
"go.abhg.dev/gs/internal/logutil"
|
||||
"go.abhg.dev/gs/internal/spice"
|
||||
"go.abhg.dev/gs/internal/spice/state"
|
||||
"go.abhg.dev/gs/internal/spice/state/storage"
|
||||
@@ -33,7 +33,7 @@ func TestListChangeTemplates(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
repo, err := git.Clone(ctx, upstream.Dir(), t.TempDir(), git.CloneOptions{
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -45,7 +45,7 @@ func TestListChangeTemplates(t *testing.T) {
|
||||
AnyTimes()
|
||||
|
||||
store := newMemoryStore(t)
|
||||
svc := spice.NewTestService(repo, store, mockForge, logtest.New(t))
|
||||
svc := spice.NewTestService(repo, store, mockForge, logutil.TestLogger(t))
|
||||
|
||||
tmpl := &forge.ChangeTemplate{
|
||||
Filename: "CHANGE_TEMPLATE.md",
|
||||
@@ -120,7 +120,7 @@ func newMemoryStore(t *testing.T) *state.Store {
|
||||
store, err := state.InitStore(ctx, state.InitStoreRequest{
|
||||
DB: db,
|
||||
Trunk: "main",
|
||||
Log: logtest.New(t),
|
||||
Log: logutil.TestLogger(t),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user