Skip to content

Commit

Permalink
feat: add support for pushing arbitrary strings to the git server usi…
Browse files Browse the repository at this point in the history
…ng push options (#93)
  • Loading branch information
purpleclay authored May 16, 2023
1 parent 1a02e03 commit 6049cf2
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
7 changes: 7 additions & 0 deletions gittest/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ func InitRepository(t *testing.T, opts ...RepositoryOption) {
changeToDir(t, tmpDir)

Exec(t, fmt.Sprintf("git init --bare --initial-branch %s %s", DefaultBranch, BareRepositoryName))
setRemoteConfig(t, BareRepositoryName)
cloneRemoteAndInit(t, ClonedRepositoryName)

// Process any provided options to ensure repository is initialized as required
Expand Down Expand Up @@ -327,6 +328,12 @@ func changeToDir(t *testing.T, dir string) string {
return changedFrom
}

func setRemoteConfig(t *testing.T, dir string) {
currentDir := changeToDir(t, dir)
setConfig(t, "receive.advertisePushOptions", "true")
changeToDir(t, currentDir)
}

func cloneRemoteAndInit(t *testing.T, cloneName string, options ...string) {
MustExec(t, fmt.Sprintf("git clone %s file://$(pwd)/%s %s", strings.Join(options, " "), BareRepositoryName, cloneName))
require.NoError(t, os.Chdir(cloneName))
Expand Down
21 changes: 18 additions & 3 deletions push.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ import (
type PushOption func(*pushOptions)

type pushOptions struct {
All bool
Tags bool
RefSpecs []string
All bool
PushOptions []string
Tags bool
RefSpecs []string
}

// WithAllBranches will push all locally created branch references
Expand All @@ -54,6 +55,16 @@ func WithAllTags() PushOption {
}
}

// WithPushOptions allows any number of aribitrary strings to be pushed
// to the remote server. All options are transmitted in their received
// order. A server must have the git config setting receive.advertisePushOptions
// set to true to receive push options
func WithPushOptions(options ...string) PushOption {
return func(opts *pushOptions) {
opts.PushOptions = trim(options...)
}
}

// WithRefSpecs allows locally created references to be cherry-picked
// and pushed back to the remote. A reference (or refspec) can be as
// simple as a name, where git will automatically resolve any
Expand Down Expand Up @@ -81,6 +92,10 @@ func (c *Client) Push(opts ...PushOption) (string, error) {
var buffer strings.Builder
buffer.WriteString("git push")

for _, po := range options.PushOptions {
buffer.WriteString(" --push-option=" + po)
}

if options.All {
buffer.WriteString(" --all")
} else if options.Tags {
Expand Down
9 changes: 9 additions & 0 deletions push_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ func TestPush(t *testing.T) {
require.Equal(t, "testing git push", remoteLog[0].Message)
}

func TestPushWithPushOptions(t *testing.T) {
gittest.InitRepository(t, gittest.WithLocalCommits("testing git push options"))

client, _ := git.NewClient()
_, err := client.Push(git.WithPushOptions("option1", "option2"))

require.NoError(t, err)
}

func TestPushResolveBranchError(t *testing.T) {
nonWorkingDirectory(t)

Expand Down

0 comments on commit 6049cf2

Please sign in to comment.