@@ -69,7 +69,6 @@ import (
6969 "errors"
7070 "fmt"
7171 "os/exec"
72- "path/filepath"
7372 "strings"
7473 "sync"
7574
@@ -79,6 +78,7 @@ import (
7978 mergestrategypb "github.com/uber/submitqueue/api/base/mergestrategy/protopb"
8079 runwaymq "github.com/uber/submitqueue/api/runway/messagequeue"
8180 runwaypb "github.com/uber/submitqueue/api/runway/messagequeue/protopb"
81+ gitlocal "github.com/uber/submitqueue/platform/extension/gitworkspace/local"
8282 gitexec "github.com/uber/submitqueue/platform/git/exec"
8383 coremetrics "github.com/uber/submitqueue/platform/metrics"
8484 "github.com/uber/submitqueue/runway/extension/merger"
@@ -97,23 +97,6 @@ const (
9797 defaultCommitterEmail = "runway@submitqueue.invalid"
9898)
9999
100- // GitRuntime identifies the explicitly provided Git runtime used by the Merger.
101- type GitRuntime struct {
102- // Executable is the absolute path to the Git executable.
103- Executable string
104- // ExecPath is the absolute directory containing Git's helper executables.
105- ExecPath string
106- // TemplateDir is the absolute directory containing Git's repository
107- // templates.
108- TemplateDir string
109- // PassthroughEnv names additional environment variables to inherit from
110- // the parent process, on top of the auth and transport ones always passed
111- // through. For a deployment whose remote needs something unusual; leave
112- // empty otherwise. Names that could alter merge semantics do not belong
113- // here — the scrubbed environment is what keeps a merge reproducible.
114- PassthroughEnv []string
115- }
116-
117100// Params holds the dependencies for the git Merger.
118101type Params struct {
119102 // CheckoutPath is the absolute path to an existing git checkout that the
@@ -128,7 +111,7 @@ type Params struct {
128111 // concrete strategy (REBASE, SQUASH_REBASE, MERGE, or PROMOTE).
129112 DefaultStrategy mergestrategypb.Strategy
130113 // Runtime is the pinned Git runtime used for every invocation.
131- Runtime GitRuntime
114+ Runtime gitlocal. Runtime
132115 // MaxPushAttempts caps how many times a committing merge retries the full
133116 // reset/apply/push cycle when the remote tip moves under it. Defaults to
134117 // defaultMaxPushAttempts when zero or negative.
@@ -166,7 +149,7 @@ type gitMerger struct {
166149 remote string
167150 target string
168151 defaultStrategy mergestrategypb.Strategy
169- runtime GitRuntime
152+ runtime gitlocal. Runtime
170153 maxPushAttempts int
171154 fetchRefspecs []string
172155 checkStaleness bool
@@ -201,7 +184,7 @@ type resolvedStep struct {
201184// The checkout must already exist and have the configured remote. Runtime paths
202185// must be absolute and DefaultStrategy must be a concrete strategy.
203186func NewMerger (params Params ) (merger.Merger , error ) {
204- if err := params .Runtime .validate (); err != nil {
187+ if err := params .Runtime .Validate (); err != nil {
205188 return nil , err
206189 }
207190 if ! isConcreteStrategy (params .DefaultStrategy ) {
@@ -237,22 +220,6 @@ func NewMerger(params Params) (merger.Merger, error) {
237220 }, nil
238221}
239222
240- func (r GitRuntime ) validate () error {
241- for name , path := range map [string ]string {
242- "executable" : r .Executable ,
243- "exec path" : r .ExecPath ,
244- "template dir" : r .TemplateDir ,
245- } {
246- if path == "" {
247- return fmt .Errorf ("git runtime %s is required" , name )
248- }
249- if ! filepath .IsAbs (path ) {
250- return fmt .Errorf ("git runtime %s must be absolute: %q" , name , path )
251- }
252- }
253- return nil
254- }
255-
256223// CheckMergeability applies the request's steps as a dry run: it verifies each
257224// step applies cleanly without committing to the remote, and returns per-step
258225// results with empty Outputs.
@@ -1025,43 +992,11 @@ func (m *gitMerger) commandAs(ctx context.Context, author authorIdent, args ...s
1025992 "-c" , "commit.gpgsign=false" ,
1026993 )
1027994 withIdentity = append (withIdentity , args ... )
1028- cmd := newGitCommand ( ctx , m .runtime , m .checkoutPath , withIdentity ... )
995+ cmd := m .runtime . Command ( ctx , m .checkoutPath , withIdentity ... )
1029996 cmd .Env = append (cmd .Env , author .env ()... )
1030997 return cmd
1031998}
1032999
1033- // newGitCommand constructs a Git command without inheriting the caller's
1034- // environment. The executable and helper paths come from the pinned runtime;
1035- // repository-local configuration remains an intentional input.
1036- func newGitCommand (ctx context.Context , runtime GitRuntime , dir string , args ... string ) * exec.Cmd {
1037- gitArgs := make ([]string , 0 , len (args )+ 3 )
1038- gitArgs = append (gitArgs ,
1039- "--exec-path=" + runtime .ExecPath ,
1040- "-c" , "init.templateDir=" + runtime .TemplateDir ,
1041- )
1042- gitArgs = append (gitArgs , args ... )
1043-
1044- cmd := exec .CommandContext (ctx , runtime .Executable , gitArgs ... )
1045- cmd .Dir = dir
1046- // HOME and XDG_CONFIG_HOME are isolated to the checkout rather than inherited,
1047- // so the runtime's literals — appended last — override any HOME a deployment
1048- // passed through. The remaining literals pin git's runtime; the scrub set and
1049- // transport variables come from the shared composer.
1050- cmd .Env = gitexec .Env (gitexec.EnvOptions {
1051- Transport : true ,
1052- Passthrough : runtime .PassthroughEnv ,
1053- Literal : []string {
1054- "HOME=" + filepath .Join (dir , ".submitqueue-git-home" ),
1055- "XDG_CONFIG_HOME=" + filepath .Join (dir , ".submitqueue-git-home" , "xdg" ),
1056- "GIT_EXEC_PATH=" + runtime .ExecPath ,
1057- "GIT_TEMPLATE_DIR=" + runtime .TemplateDir ,
1058- "LC_ALL=C" ,
1059- "LANG=C" ,
1060- },
1061- })
1062- return cmd
1063- }
1064-
10651000// isConcreteStrategy reports whether s names a concrete integration strategy
10661001// (i.e. not DEFAULT and not an unknown value).
10671002func isConcreteStrategy (s mergestrategypb.Strategy ) bool {
0 commit comments