-
Notifications
You must be signed in to change notification settings - Fork 787
repository: adopt variadic options pattern for Init and PlainInit #1462
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v6-transport
Are you sure you want to change the base?
repository: adopt variadic options pattern for Init and PlainInit #1462
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@davidalpert thank you for putting this together. I added a few comments, PTAL.
We may have some additional challenges when expanding the variadic options to Clone
, to keep the API simple and avoid the name collision on the With
funcs.
options.go
Outdated
type plainInitOptions struct { | ||
initOptions []InitOption | ||
|
||
bare bool | ||
objectFormat formatcfg.ObjectFormat |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A different approach would be to collapse all the init options into a single struct and remove
PlainInit
, replacing it withInit
and the options that configure a bare repo.
I like this idea for the long-term. But I think I'd keep PlainInit
largely as-is and without additional options for v6
. So we abstracted away the complexity from the user by calling Init
with sensible defaults. This should provide an easier transition for users using PlainInit
in v5
.
Potentially we could mark it as deprecated, to be removed at v7
. But this would depend on what the API would look like across all the Plain
funcs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addressed in 2407eb47; if approved I can rebase and squash into a single commit.
repository.go
Outdated
func InitWithOptions(s storage.Storer, worktree billy.Filesystem, options InitOptions) (*Repository, error) { | ||
if err := initStorer(s); err != nil { | ||
return nil, err | ||
func InitWithOptions(s storage.Storer, worktree billy.Filesystem, opts ...InitOption) (*Repository, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd remove the InitWithOptions
func. From the Init
func I'd remove the worktree
arg (which is optional) and make it part of the variadic options:
func Init(s storage.Storer, opts ...InitOption) (*Repository, error)
This way, an init call with a given storer would look like:
git.Init(storer)
And more advanced options:
git.Init(storer,
git.WithWorkTree(fs),
git.WithObjectFormat(f))
Which would remove the need to pass on nil
to an optional arg.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addressed in 2407eb47; if approved I can rebase and squash into a single commit.
ef4c87e
to
2407eb4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@davidalpert overall LGTM.
One additional change needed is to replace the PlainInitWithOptions
from _examples/sha256
.
Please squash your commits and rebase (and retarget the PR) against v6-transport branch instead? We already bumped the API version on that branch to v6
so we would be able to merge this right away.
repository.go
Outdated
// WithBare is for backwards compatibility and is the opposite of WithWorkTree; a bare repo sets the worktree to nil. | ||
func WithBare() InitOption { | ||
return func(o *initOptions) { | ||
o.workTree = nil | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand the idea behind having something for users to relate to. But it feels largely redundant.
// WithBare is for backwards compatibility and is the opposite of WithWorkTree; a bare repo sets the worktree to nil. | |
func WithBare() InitOption { | |
return func(o *initOptions) { | |
o.workTree = nil | |
} | |
} |
repository.go
Outdated
// WithWorkTree sets the internal worktree for the new repo. | ||
func WithWorkTree(worktree billy.Filesystem) InitOption { | ||
return func(o *initOptions) { | ||
o.workTree = worktree | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// WithWorkTree sets the internal worktree for the new repo. | |
func WithWorkTree(worktree billy.Filesystem) InitOption { | |
return func(o *initOptions) { | |
o.workTree = worktree | |
} | |
} | |
// WithWorkTree sets the worktree filesystem for the repo. If not used, or a `nil` is | |
// passed as argument, will result in a bare repository. | |
func WithWorkTree(worktree billy.Filesystem) InitOption { | |
return func(o *initOptions) { | |
o.workTree = worktree | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will remove WithBare(..)
and incorporate this comment update in my rebased PR.
given the updated comments on WithWorkTree(..)
what is the significance of keeping the isBare
argument in
func PlainInit(path string, isBare bool, options ...InitOption) (*Repository, error) {
...
}
perhaps it makes sense to remove isBare bool
there and leave the signature as
func PlainInit(path string, options ...InitOption) (*Repository, error) {
...
}
so that there is one consistent syntax for a repository as both Init
and PlainInit
default to a bare repo unless a worktree is passed using WithWorkTree(...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, tests are failing for me locally on the v6-transport
branch before I rebase my changes...
❯ make test
running against git version 2.35.1
...
--- FAIL: TestProxyEnvSuite (0.35s)
--- FAIL: TestProxyEnvSuite/TestCommand (0.34s)
testing.go:1399: race detected during execution of test
FAIL
FAIL github.com/go-git/go-git/v6/internal/transport/ssh/test 2.317s
...
repository.go
Outdated
} | ||
} | ||
|
||
// WithObjectFormat sets the object format when invoking PlainInitWithOptions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// WithObjectFormat sets the object format when invoking PlainInitWithOptions. | |
// WithObjectFormat sets the repository's object format. |
type initOptions struct { | ||
defaultBranch plumbing.ReferenceName | ||
workTree billy.Filesystem | ||
objectFormat formatcfg.ObjectFormat | ||
} | ||
|
||
func newInitOptions() initOptions { | ||
return initOptions{ | ||
defaultBranch: plumbing.Master, | ||
workTree: nil, | ||
objectFormat: "", | ||
} | ||
} | ||
|
||
type InitOption func(*initOptions) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the purposes of this PR, we can leave this as-is. However, as we expand other parts of the code we may need to amend this so that we can enable the reuse of the same With<Option>
across different use cases (e.g. Init
, Clone
, etc), without having to prefix them.
Let's leave this comment open for future reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had the same thought here, looking ahead to the possibility of future collisions, especially after initially running into them between Init
and PlainInit
.
One possibility that comes to mind is establishing a policy that all With<Option>
functions need to be in a scoped package which helps guide clients into using the right option set for the package, e.g. repo.WithWorkTree(...)
rather than git.WithWorkTree(...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The --bare
option is one that may collide, for example, as both git init --bare
and git clone --bare
are supported by the CLI; although both could be under a common "repo options" it may make more sense to support init options and clone options independently and simply repeat shared options with consistent semantics (e.g. init.WithWorkTree(...)
and clone.WithWorkTree(...)
)
2407eb4
to
5ed5b8b
Compare
|
this commit removes InitWithOptions by collapsing it back into Init(storage, opt...) NOTE: this is a breaking change for the syntax of calling Init as the type of the second option has changed and instead of calling Init(storage, worktree) we now call Init(storage, WithWorkTree(worktree))
5ed5b8b
to
256f784
Compare
rebased again on top of |
This PR refactors the options for the Repository
Init
andPlainInit
methods to accept some variadic style options in the same style as the recently refactored packfile.Parser.This refactoring for the repository factory functions paves the way for additional options to opt-in to legacy v5 configuration handlings (see #395 and the initial work in #1019)
I am looking for feedback to confirm that this syntax and semantics are going in an aligned direction. Specifically I ran into the similarity between
Init
andPlainInit
args and the fact that Golang does not support two functions named the same of different types (e.g.WithDefaultBranch
might becomeWithPlainInitDefaultBranch
but that seems to add no value) so I compromised and introduced aWithInitOptions
helper that allows passinginitOption
helpers into theplainInitOption
's innerinitOptions
A different approach would be to collapse all the init options into a single struct and remove
PlainInit
, replacing it withInit
and the options that configure a bare repo.@pjbgf I am looking for some confirmation or direction on this set of changes before I push forward to address the rest of #395