Skip to content

Commit cadf8b0

Browse files
committed
repo: refactor into RepoProvider interface
Refactor 'repo.go', changing its standalone functions into methods of a 'RepoProvider' interface. This allows for some simplification of helper struct (e.g. FileSystem) accesses, sets up for future unit testing work by making it a mockable interface, and propagates the 'TraceLogger' struct to its functions. In particular, the logger will be used in later patches to set up region tracing for various functions in the file. Signed-off-by: Victoria Dye <[email protected]>
1 parent 8f027ee commit cadf8b0

File tree

10 files changed

+84
-45
lines changed

10 files changed

+84
-45
lines changed

cmd/git-bundle-server/delete.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,14 @@ func (d *deleteCmd) Run(ctx context.Context, args []string) error {
3737
route := parser.PositionalString("route", "the route to delete")
3838
parser.Parse(ctx, args)
3939

40-
repo, err := core.CreateRepository(*route)
40+
repoProvider := utils.GetDependency[core.RepositoryProvider](ctx, d.container)
41+
42+
repo, err := repoProvider.CreateRepository(ctx, *route)
4143
if err != nil {
4244
return d.logger.Error(ctx, err)
4345
}
4446

45-
err = core.RemoveRoute(*route)
47+
err = repoProvider.RemoveRoute(ctx, *route)
4648
if err != nil {
4749
return d.logger.Error(ctx, err)
4850
}

cmd/git-bundle-server/init.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ func (i *initCmd) Run(ctx context.Context, args []string) error {
4141
route := parser.PositionalString("route", "the route to host the specified repo")
4242
parser.Parse(ctx, args)
4343

44-
repo, err := core.CreateRepository(*route)
44+
repoProvider := utils.GetDependency[core.RepositoryProvider](ctx, i.container)
45+
46+
repo, err := repoProvider.CreateRepository(ctx, *route)
4547
if err != nil {
4648
return i.logger.Error(ctx, err)
4749
}

cmd/git-bundle-server/start.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@ func (s *startCmd) Run(ctx context.Context, args []string) error {
3737
route := parser.PositionalString("route", "the route for which bundles should be generated")
3838
parser.Parse(ctx, args)
3939

40+
repoProvider := utils.GetDependency[core.RepositoryProvider](ctx, s.container)
41+
4042
// CreateRepository registers the route.
41-
repo, err := core.CreateRepository(*route)
43+
repo, err := repoProvider.CreateRepository(ctx, *route)
4244
if err != nil {
4345
return s.logger.Error(ctx, err)
4446
}

cmd/git-bundle-server/stop.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ func (s *stopCmd) Run(ctx context.Context, args []string) error {
3636
route := parser.PositionalString("route", "the route for which bundles should stop being generated")
3737
parser.Parse(ctx, args)
3838

39-
err := core.RemoveRoute(*route)
39+
repoProvider := utils.GetDependency[core.RepositoryProvider](ctx, s.container)
40+
41+
err := repoProvider.RemoveRoute(ctx, *route)
4042
if err != nil {
4143
s.logger.Error(ctx, err)
4244
}

cmd/git-bundle-server/update-all.go

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77

88
"github.com/github/git-bundle-server/cmd/utils"
99
"github.com/github/git-bundle-server/internal/argparse"
10-
"github.com/github/git-bundle-server/internal/common"
1110
"github.com/github/git-bundle-server/internal/core"
1211
"github.com/github/git-bundle-server/internal/log"
1312
)
@@ -34,23 +33,19 @@ For every configured route, run 'git-bundle-server update <options> <route>'.`
3433
}
3534

3635
func (u *updateAllCmd) Run(ctx context.Context, args []string) error {
37-
user, err := utils.GetDependency[common.UserProvider](ctx, u.container).CurrentUser()
38-
if err != nil {
39-
return u.logger.Error(ctx, err)
40-
}
41-
fs := utils.GetDependency[common.FileSystem](ctx, u.container)
42-
4336
parser := argparse.NewArgParser(u.logger, "git-bundle-server update-all")
4437
parser.Parse(ctx, args)
4538

46-
exe, err := os.Executable()
39+
repoProvider := utils.GetDependency[core.RepositoryProvider](ctx, u.container)
40+
41+
repos, err := repoProvider.GetRepositories(ctx)
4742
if err != nil {
48-
return u.logger.Errorf(ctx, "failed to get path to execuable: %w", err)
43+
return u.logger.Error(ctx, err)
4944
}
5045

51-
repos, err := core.GetRepositories(user, fs)
46+
exe, err := os.Executable()
5247
if err != nil {
53-
return u.logger.Error(ctx, err)
48+
return u.logger.Errorf(ctx, "failed to get path to execuable: %w", err)
5449
}
5550

5651
subargs := []string{"update", ""}

cmd/git-bundle-server/update.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ func (u *updateCmd) Run(ctx context.Context, args []string) error {
3939
route := parser.PositionalString("route", "the route to update")
4040
parser.Parse(ctx, args)
4141

42-
repo, err := core.CreateRepository(*route)
42+
repoProvider := utils.GetDependency[core.RepositoryProvider](ctx, u.container)
43+
44+
repo, err := repoProvider.CreateRepository(ctx, *route)
4345
if err != nil {
4446
return u.logger.Error(ctx, err)
4547
}

cmd/git-bundle-web-server/bundle-server.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,7 @@ func (b *bundleWebServer) parseRoute(ctx context.Context, path string) (string,
6666
func (b *bundleWebServer) serve(w http.ResponseWriter, r *http.Request) {
6767
ctx := r.Context()
6868

69-
user, err := common.NewUserProvider().CurrentUser()
70-
if err != nil {
71-
return
72-
}
73-
fs := common.NewFileSystem()
7469
path := r.URL.Path
75-
7670
owner, repo, file, err := b.parseRoute(ctx, path)
7771
if err != nil {
7872
w.WriteHeader(http.StatusNotFound)
@@ -82,7 +76,11 @@ func (b *bundleWebServer) serve(w http.ResponseWriter, r *http.Request) {
8276

8377
route := owner + "/" + repo
8478

85-
repos, err := core.GetRepositories(user, fs)
79+
userProvider := common.NewUserProvider()
80+
fileSystem := common.NewFileSystem()
81+
repoProvider := core.NewRepositoryProvider(b.logger, userProvider, fileSystem)
82+
83+
repos, err := repoProvider.GetRepositories(ctx)
8684
if err != nil {
8785
w.WriteHeader(http.StatusInternalServerError)
8886
fmt.Printf("Failed to load routes\n")

cmd/utils/container-helpers.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55

66
"github.com/github/git-bundle-server/internal/common"
7+
"github.com/github/git-bundle-server/internal/core"
78
"github.com/github/git-bundle-server/internal/daemon"
89
"github.com/github/git-bundle-server/internal/log"
910
)
@@ -19,6 +20,13 @@ func BuildGitBundleServerContainer(logger log.TraceLogger) *DependencyContainer
1920
registerDependency(container, func(ctx context.Context) common.FileSystem {
2021
return common.NewFileSystem()
2122
})
23+
registerDependency(container, func(ctx context.Context) core.RepositoryProvider {
24+
return core.NewRepositoryProvider(
25+
logger,
26+
GetDependency[common.UserProvider](ctx, container),
27+
GetDependency[common.FileSystem](ctx, container),
28+
)
29+
})
2230
registerDependency(container, func(ctx context.Context) daemon.DaemonProvider {
2331
t, err := daemon.NewDaemonProvider(
2432
logger,

internal/core/repo.go

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package core
22

33
import (
4+
"context"
45
"fmt"
5-
"log"
66
"os"
7-
"os/user"
87

98
"github.com/github/git-bundle-server/internal/common"
9+
"github.com/github/git-bundle-server/internal/log"
1010
)
1111

1212
type Repository struct {
@@ -15,13 +15,36 @@ type Repository struct {
1515
WebDir string
1616
}
1717

18-
func CreateRepository(route string) (*Repository, error) {
19-
user, err := common.NewUserProvider().CurrentUser()
18+
type RepositoryProvider interface {
19+
CreateRepository(ctx context.Context, route string) (*Repository, error)
20+
GetRepositories(ctx context.Context) (map[string]Repository, error)
21+
RemoveRoute(ctx context.Context, route string) error
22+
}
23+
24+
type repoProvider struct {
25+
logger log.TraceLogger
26+
user common.UserProvider
27+
fileSystem common.FileSystem
28+
}
29+
30+
func NewRepositoryProvider(logger log.TraceLogger,
31+
u common.UserProvider,
32+
fs common.FileSystem,
33+
) RepositoryProvider {
34+
return &repoProvider{
35+
logger: logger,
36+
user: u,
37+
fileSystem: fs,
38+
}
39+
}
40+
41+
func (r *repoProvider) CreateRepository(ctx context.Context, route string) (*Repository, error) {
42+
user, err := r.user.CurrentUser()
2043
if err != nil {
2144
return nil, err
2245
}
23-
fs := common.NewFileSystem()
24-
repos, err := GetRepositories(user, fs)
46+
47+
repos, err := r.GetRepositories(ctx)
2548
if err != nil {
2649
return nil, fmt.Errorf("failed to parse routes file: %w", err)
2750
}
@@ -36,7 +59,7 @@ func CreateRepository(route string) (*Repository, error) {
3659

3760
mkdirErr := os.MkdirAll(web, os.ModePerm)
3861
if mkdirErr != nil {
39-
log.Fatal("failed to create web directory: ", mkdirErr)
62+
return nil, fmt.Errorf("failed to create web directory: %w", mkdirErr)
4063
}
4164

4265
repo = Repository{
@@ -47,21 +70,16 @@ func CreateRepository(route string) (*Repository, error) {
4770

4871
repos[route] = repo
4972

50-
err = WriteRouteFile(repos)
73+
err = r.writeRouteFile(repos)
5174
if err != nil {
5275
return nil, fmt.Errorf("warning: failed to write route file")
5376
}
5477

5578
return &repo, nil
5679
}
5780

58-
func RemoveRoute(route string) error {
59-
user, err := common.NewUserProvider().CurrentUser()
60-
if err != nil {
61-
return err
62-
}
63-
fs := common.NewFileSystem()
64-
repos, err := GetRepositories(user, fs)
81+
func (r *repoProvider) RemoveRoute(ctx context.Context, route string) error {
82+
repos, err := r.GetRepositories(ctx)
6583
if err != nil {
6684
return fmt.Errorf("failed to parse routes file: %w", err)
6785
}
@@ -73,11 +91,11 @@ func RemoveRoute(route string) error {
7391

7492
delete(repos, route)
7593

76-
return WriteRouteFile(repos)
94+
return r.writeRouteFile(repos)
7795
}
7896

79-
func WriteRouteFile(repos map[string]Repository) error {
80-
user, err := common.NewUserProvider().CurrentUser()
97+
func (r *repoProvider) writeRouteFile(repos map[string]Repository) error {
98+
user, err := r.user.CurrentUser()
8199
if err != nil {
82100
return err
83101
}
@@ -93,13 +111,18 @@ func WriteRouteFile(repos map[string]Repository) error {
93111
return os.WriteFile(routefile, []byte(contents), 0o600)
94112
}
95113

96-
func GetRepositories(user *user.User, fs common.FileSystem) (map[string]Repository, error) {
114+
func (r *repoProvider) GetRepositories(ctx context.Context) (map[string]Repository, error) {
115+
user, err := r.user.CurrentUser()
116+
if err != nil {
117+
return nil, err
118+
}
119+
97120
repos := make(map[string]Repository)
98121

99122
dir := bundleroot(user)
100123
routefile := dir + "/routes"
101124

102-
lines, err := fs.ReadFileLines(routefile)
125+
lines, err := r.fileSystem.ReadFileLines(routefile)
103126
if err != nil {
104127
return nil, err
105128
}

internal/core/repo_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package core_test
22

33
import (
4+
"context"
45
"errors"
56
"os/user"
67
"testing"
@@ -83,12 +84,16 @@ var getRepositoriesTests = []struct {
8384
}
8485

8586
func TestRepos_GetRepositories(t *testing.T) {
87+
testLogger := &MockTraceLogger{}
8688
testFileSystem := &MockFileSystem{}
8789
testUser := &user.User{
8890
Uid: "123",
8991
Username: "testuser",
9092
HomeDir: "/my/test/dir",
9193
}
94+
testUserProvider := &MockUserProvider{}
95+
testUserProvider.On("CurrentUser").Return(testUser, nil)
96+
repoProvider := core.NewRepositoryProvider(testLogger, testUserProvider, testFileSystem)
9297

9398
for _, tt := range getRepositoriesTests {
9499
t.Run(tt.title, func(t *testing.T) {
@@ -97,7 +102,7 @@ func TestRepos_GetRepositories(t *testing.T) {
97102
mock.AnythingOfType("string"),
98103
).Return(tt.readFileLines.First, tt.readFileLines.Second).Once()
99104

100-
actual, err := core.GetRepositories(testUser, testFileSystem)
105+
actual, err := repoProvider.GetRepositories(context.Background())
101106

102107
if tt.expectedErr {
103108
assert.NotNil(t, err, "Expected error")

0 commit comments

Comments
 (0)