diff --git a/cmd/werf/build/main.go b/cmd/werf/build/main.go index 7652fb68cd..da3fcfa35a 100644 --- a/cmd/werf/build/main.go +++ b/cmd/werf/build/main.go @@ -155,7 +155,7 @@ func runMain(ctx context.Context, args []string) error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } @@ -172,7 +172,7 @@ func runMain(ctx context.Context, args []string) error { } }() - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } diff --git a/cmd/werf/bundle/export/export.go b/cmd/werf/bundle/export/export.go index 70b182b1e1..4f6adf88ec 100644 --- a/cmd/werf/bundle/export/export.go +++ b/cmd/werf/bundle/export/export.go @@ -155,7 +155,7 @@ func runExport(ctx context.Context) error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } @@ -169,7 +169,7 @@ func runExport(ctx context.Context) error { } }() - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } diff --git a/cmd/werf/bundle/publish/publish.go b/cmd/werf/bundle/publish/publish.go index f052d0730b..feec40583b 100644 --- a/cmd/werf/bundle/publish/publish.go +++ b/cmd/werf/bundle/publish/publish.go @@ -171,7 +171,7 @@ func runPublish(ctx context.Context) error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } @@ -185,7 +185,7 @@ func runPublish(ctx context.Context) error { } }() - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } diff --git a/cmd/werf/ci_env/ci_env.go b/cmd/werf/ci_env/ci_env.go index 2dfdf72ce8..655d89d142 100644 --- a/cmd/werf/ci_env/ci_env.go +++ b/cmd/werf/ci_env/ci_env.go @@ -102,7 +102,7 @@ func runCIEnv(cmd *cobra.Command, args []string) error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } @@ -343,7 +343,7 @@ func generateGithubEnvs(ctx context.Context, w io.Writer, dockerConfig string) e func generateGithubDefaultRepo(ctx context.Context, defaultRegistry, ciGithubDockerPackage string) (string, error) { var defaultRepo string if ciGithubDockerPackage != "" { - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return "", err } diff --git a/cmd/werf/cleanup/cleanup.go b/cmd/werf/cleanup/cleanup.go index f1d7e33c74..3753a842af 100644 --- a/cmd/werf/cleanup/cleanup.go +++ b/cmd/werf/cleanup/cleanup.go @@ -116,7 +116,7 @@ func runCleanup(ctx context.Context) error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } @@ -143,7 +143,7 @@ func runCleanup(ctx context.Context) error { return err } - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } @@ -162,7 +162,7 @@ func runCleanup(ctx context.Context) error { } if !werfConfig.Meta.GitWorktree.GetForceShallowClone() && !werfConfig.Meta.GitWorktree.GetAllowFetchingOriginBranchesAndTags() { - isShallow, err := giterminismManager.LocalGitRepo().IsShallowClone() + isShallow, err := giterminismManager.LocalGitRepo().IsShallowClone(ctx) if err != nil { return fmt.Errorf("check shallow clone failed: %s", err) } diff --git a/cmd/werf/common/common.go b/cmd/werf/common/common.go index 3955cf34c8..14699cec9f 100644 --- a/cmd/werf/common/common.go +++ b/cmd/werf/common/common.go @@ -1163,10 +1163,10 @@ func GetWerfConfigOptions(cmdData *CmdData, logRenderedFilePath bool) config.Wer } } -func GetGiterminismManager(cmdData *CmdData) (giterminism_manager.Interface, error) { +func GetGiterminismManager(ctx context.Context, cmdData *CmdData) (giterminism_manager.Interface, error) { workingDir := GetWorkingDir(cmdData) - gitWorkTree, err := GetGitWorkTree(cmdData, workingDir) + gitWorkTree, err := GetGitWorkTree(ctx, cmdData, workingDir) if err != nil { return nil, err } @@ -1200,11 +1200,11 @@ func GetGiterminismManager(cmdData *CmdData) (giterminism_manager.Interface, err }) } -func GetGitWorkTree(cmdData *CmdData, workingDir string) (string, error) { +func GetGitWorkTree(ctx context.Context, cmdData *CmdData, workingDir string) (string, error) { if *cmdData.GitWorkTree != "" { workTree := *cmdData.GitWorkTree - if isValid, err := true_git.IsValidWorkTree(workTree); err != nil { + if isValid, err := true_git.IsValidWorkTree(ctx, workTree); err != nil { return "", err } else if isValid { return util.GetAbsoluteFilepath(workTree), nil @@ -1213,7 +1213,7 @@ func GetGitWorkTree(cmdData *CmdData, workingDir string) (string, error) { return "", fmt.Errorf("werf requires a git work tree for the project to exist: not a valid git work tree %q specified", workTree) } - if found, workTree, err := true_git.UpwardLookupAndVerifyWorkTree(workingDir); err != nil { + if found, workTree, err := true_git.UpwardLookupAndVerifyWorkTree(ctx, workingDir); err != nil { return "", err } else if found { return util.GetAbsoluteFilepath(workTree), nil diff --git a/cmd/werf/common/follow.go b/cmd/werf/common/follow.go index 411b777253..11b5689705 100644 --- a/cmd/werf/common/follow.go +++ b/cmd/werf/common/follow.go @@ -21,7 +21,7 @@ func FollowGitHead(ctx context.Context, cmdData *CmdData, taskFunc func(ctx cont var savedHeadCommit string iterFunc := func() error { - giterminismManager, err := GetGiterminismManager(cmdData) + giterminismManager, err := GetGiterminismManager(ctx, cmdData) if err != nil { return fmt.Errorf("unable to get giterminism manager: %s", err) } diff --git a/cmd/werf/compose/main.go b/cmd/werf/compose/main.go index a9d69455f9..05372bdd91 100644 --- a/cmd/werf/compose/main.go +++ b/cmd/werf/compose/main.go @@ -317,7 +317,7 @@ func runMain(ctx context.Context, dockerComposeCmdName string, cmdData composeCm return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } @@ -331,7 +331,7 @@ func runMain(ctx context.Context, dockerComposeCmdName string, cmdData composeCm } }() - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } diff --git a/cmd/werf/config/list/list.go b/cmd/werf/config/list/list.go index 180d89f7d6..aeb19402a8 100644 --- a/cmd/werf/config/list/list.go +++ b/cmd/werf/config/list/list.go @@ -68,11 +68,11 @@ func run() error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } diff --git a/cmd/werf/config/render/render.go b/cmd/werf/config/render/render.go index 1921be7f22..9410a13938 100644 --- a/cmd/werf/config/render/render.go +++ b/cmd/werf/config/render/render.go @@ -41,11 +41,11 @@ func NewCmd() *cobra.Command { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } diff --git a/cmd/werf/converge/converge.go b/cmd/werf/converge/converge.go index c301ca22bb..5a90ead129 100644 --- a/cmd/werf/converge/converge.go +++ b/cmd/werf/converge/converge.go @@ -195,7 +195,7 @@ func runMain(ctx context.Context) error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } @@ -209,7 +209,7 @@ func runMain(ctx context.Context) error { } }() - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } diff --git a/cmd/werf/dismiss/dismiss.go b/cmd/werf/dismiss/dismiss.go index 66f5704c60..d81452e675 100644 --- a/cmd/werf/dismiss/dismiss.go +++ b/cmd/werf/dismiss/dismiss.go @@ -143,7 +143,7 @@ func runDismiss(ctx context.Context) error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } @@ -157,7 +157,7 @@ func runDismiss(ctx context.Context) error { common.LogKubeContext(kube.Context) - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } diff --git a/cmd/werf/export/export.go b/cmd/werf/export/export.go index 8de9011c01..5b87ea4a33 100644 --- a/cmd/werf/export/export.go +++ b/cmd/werf/export/export.go @@ -136,7 +136,7 @@ func run(ctx context.Context, imagesToProcess, tagTemplateList []string) error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } @@ -144,7 +144,7 @@ func run(ctx context.Context, imagesToProcess, tagTemplateList []string) error { return err } - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } diff --git a/cmd/werf/helm/get_autogenerated_values.go b/cmd/werf/helm/get_autogenerated_values.go index 1bf8527888..882f461f4a 100644 --- a/cmd/werf/helm/get_autogenerated_values.go +++ b/cmd/werf/helm/get_autogenerated_values.go @@ -120,7 +120,7 @@ func runGetServiceValues(ctx context.Context) error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *getAutogeneratedValuedCmdData.LogVerbose || *getAutogeneratedValuedCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *getAutogeneratedValuedCmdData.LogVerbose || *getAutogeneratedValuedCmdData.LogDebug}); err != nil { return err } @@ -128,7 +128,7 @@ func runGetServiceValues(ctx context.Context) error { return err } - giterminismManager, err := common.GetGiterminismManager(&getAutogeneratedValuedCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &getAutogeneratedValuedCmdData) if err != nil { return err } diff --git a/cmd/werf/helm/get_namespace.go b/cmd/werf/helm/get_namespace.go index 6ea53d5f0c..66cfb7c50c 100644 --- a/cmd/werf/helm/get_namespace.go +++ b/cmd/werf/helm/get_namespace.go @@ -62,11 +62,11 @@ func runGetNamespace() error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *getNamespaceCmdData.LogVerbose || *getNamespaceCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *getNamespaceCmdData.LogVerbose || *getNamespaceCmdData.LogDebug}); err != nil { return err } - giterminismManager, err := common.GetGiterminismManager(&getNamespaceCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &getNamespaceCmdData) if err != nil { return err } diff --git a/cmd/werf/helm/get_release.go b/cmd/werf/helm/get_release.go index 3cf49e35db..126a366e0a 100644 --- a/cmd/werf/helm/get_release.go +++ b/cmd/werf/helm/get_release.go @@ -62,11 +62,11 @@ func runGetRelease() error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *getReleaseCmdData.LogVerbose || *getReleaseCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *getReleaseCmdData.LogVerbose || *getReleaseCmdData.LogDebug}); err != nil { return err } - giterminismManager, err := common.GetGiterminismManager(&getReleaseCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &getReleaseCmdData) if err != nil { return err } diff --git a/cmd/werf/helm/secret/rotate_secret_key/rotate_secret_key.go b/cmd/werf/helm/secret/rotate_secret_key/rotate_secret_key.go index aaa7ea3ad2..231bb2d779 100644 --- a/cmd/werf/helm/secret/rotate_secret_key/rotate_secret_key.go +++ b/cmd/werf/helm/secret/rotate_secret_key/rotate_secret_key.go @@ -80,11 +80,11 @@ func runRotateSecretKey(ctx context.Context, cmd *cobra.Command, secretValuesPat return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } diff --git a/cmd/werf/host/cleanup/cleanup.go b/cmd/werf/host/cleanup/cleanup.go index 243b6428cb..4499a38de7 100644 --- a/cmd/werf/host/cleanup/cleanup.go +++ b/cmd/werf/host/cleanup/cleanup.go @@ -111,7 +111,7 @@ func runGC(ctx context.Context) error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } diff --git a/cmd/werf/managed_images/add/add.go b/cmd/werf/managed_images/add/add.go index 8014046770..4b5e1f302e 100644 --- a/cmd/werf/managed_images/add/add.go +++ b/cmd/werf/managed_images/add/add.go @@ -100,7 +100,7 @@ func run(ctx context.Context, imageName string) error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } @@ -122,7 +122,7 @@ func run(ctx context.Context, imageName string) error { } defer tmp_manager.ReleaseProjectDir(projectTmpDir) - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } diff --git a/cmd/werf/managed_images/ls/ls.go b/cmd/werf/managed_images/ls/ls.go index 011fff18c5..4cb8a7c414 100644 --- a/cmd/werf/managed_images/ls/ls.go +++ b/cmd/werf/managed_images/ls/ls.go @@ -96,7 +96,7 @@ func run(ctx context.Context) error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } @@ -118,7 +118,7 @@ func run(ctx context.Context) error { } defer tmp_manager.ReleaseProjectDir(projectTmpDir) - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } diff --git a/cmd/werf/managed_images/rm/rm.go b/cmd/werf/managed_images/rm/rm.go index 435a8b44ac..2d396ebf22 100644 --- a/cmd/werf/managed_images/rm/rm.go +++ b/cmd/werf/managed_images/rm/rm.go @@ -100,7 +100,7 @@ func run(ctx context.Context, imageNames []string) error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } @@ -122,7 +122,7 @@ func run(ctx context.Context, imageNames []string) error { } defer tmp_manager.ReleaseProjectDir(projectTmpDir) - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } diff --git a/cmd/werf/purge/purge.go b/cmd/werf/purge/purge.go index aa0e843f85..cc25077aae 100644 --- a/cmd/werf/purge/purge.go +++ b/cmd/werf/purge/purge.go @@ -108,7 +108,7 @@ func runPurge(ctx context.Context) error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } @@ -120,7 +120,7 @@ func runPurge(ctx context.Context) error { return err } - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } diff --git a/cmd/werf/render/render.go b/cmd/werf/render/render.go index d5d69319f3..3db653a2df 100644 --- a/cmd/werf/render/render.go +++ b/cmd/werf/render/render.go @@ -160,11 +160,11 @@ func runRender(ctx context.Context) error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } diff --git a/cmd/werf/run/run.go b/cmd/werf/run/run.go index d49ce42d03..330f4ced3d 100644 --- a/cmd/werf/run/run.go +++ b/cmd/werf/run/run.go @@ -244,7 +244,7 @@ func runMain(ctx context.Context) error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } @@ -252,7 +252,7 @@ func runMain(ctx context.Context) error { return err } - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } diff --git a/cmd/werf/stage/image/main.go b/cmd/werf/stage/image/main.go index 50f092e437..4be08e106f 100644 --- a/cmd/werf/stage/image/main.go +++ b/cmd/werf/stage/image/main.go @@ -119,7 +119,7 @@ func run(ctx context.Context, imageName string) error { return err } - if err := true_git.Init(true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { + if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil { return err } @@ -127,7 +127,7 @@ func run(ctx context.Context, imageName string) error { return err } - giterminismManager, err := common.GetGiterminismManager(&commonCmdData) + giterminismManager, err := common.GetGiterminismManager(ctx, &commonCmdData) if err != nil { return err } diff --git a/pkg/build/conveyor.go b/pkg/build/conveyor.go index 9102270d55..51339a2a26 100644 --- a/pkg/build/conveyor.go +++ b/pkg/build/conveyor.go @@ -909,7 +909,7 @@ func generateGitMappings(ctx context.Context, imageBaseConfig *config.StapelImag localGitRepo := c.giterminismManager.LocalGitRepo() if !c.werfConfig.Meta.GitWorktree.GetForceShallowClone() { - isShallowClone, err := localGitRepo.IsShallowClone() + isShallowClone, err := localGitRepo.IsShallowClone(ctx) if err != nil { return nil, fmt.Errorf("check shallow clone failed: %s", err) } diff --git a/pkg/git_repo/base.go b/pkg/git_repo/base.go index 6db55e9621..6d62a6e854 100644 --- a/pkg/git_repo/base.go +++ b/pkg/git_repo/base.go @@ -122,8 +122,8 @@ func (repo *Base) isEmpty(ctx context.Context, repoPath string) (bool, error) { return false, nil } -func getHeadCommit(repoPath string) (string, error) { - res, err := true_git.ShowRef(repoPath) +func getHeadCommit(ctx context.Context, repoPath string) (string, error) { + res, err := true_git.ShowRef(ctx, repoPath) if err != nil { return "", err } diff --git a/pkg/git_repo/local.go b/pkg/git_repo/local.go index bf9bec12a3..f1e768bb10 100644 --- a/pkg/git_repo/local.go +++ b/pkg/git_repo/local.go @@ -54,12 +54,12 @@ func OpenLocalRepo(ctx context.Context, name, workTreeDir string, opts OpenLocal return l, err } - gitDir, err := true_git.ResolveRepoDir(filepath.Join(workTreeDir, git.GitDirName)) + gitDir, err := true_git.ResolveRepoDir(ctx, filepath.Join(workTreeDir, git.GitDirName)) if err != nil { return l, fmt.Errorf("unable to resolve git repo dir for %s: %s", workTreeDir, err) } - l, err = newLocal(name, workTreeDir, gitDir) + l, err = newLocal(ctx, name, workTreeDir, gitDir) if err != nil { return l, err } @@ -99,8 +99,8 @@ func OpenLocalRepo(ctx context.Context, name, workTreeDir string, opts OpenLocal return l, nil } -func newLocal(name, workTreeDir, gitDir string) (l *Local, err error) { - headCommit, err := getHeadCommit(workTreeDir) +func newLocal(ctx context.Context, name, workTreeDir, gitDir string) (l *Local, err error) { + headCommit, err := getHeadCommit(ctx, workTreeDir) if err != nil { return l, fmt.Errorf("unable to get git repo head commit: %s", err) } @@ -125,7 +125,7 @@ func (repo *Local) PlainOpen() (*git.Repository, error) { } func (repo *Local) SyncWithOrigin(ctx context.Context) error { - isShallow, err := repo.IsShallowClone() + isShallow, err := repo.IsShallowClone(ctx) if err != nil { return fmt.Errorf("check shallow clone failed: %s", err) } @@ -156,7 +156,7 @@ func (repo *Local) SyncWithOrigin(ctx context.Context) error { } func (repo *Local) FetchOrigin(ctx context.Context) error { - isShallow, err := repo.IsShallowClone() + isShallow, err := repo.IsShallowClone(ctx) if err != nil { return fmt.Errorf("check shallow clone failed: %s", err) } @@ -184,8 +184,8 @@ func (repo *Local) FetchOrigin(ctx context.Context) error { }) } -func (repo *Local) IsShallowClone() (bool, error) { - return true_git.IsShallowClone(repo.WorkTreeDir) +func (repo *Local) IsShallowClone(ctx context.Context) (bool, error) { + return true_git.IsShallowClone(ctx, repo.WorkTreeDir) } func (repo *Local) CreateDetachedMergeCommit(ctx context.Context, fromCommit, toCommit string) (string, error) { @@ -216,8 +216,8 @@ func (repo *Local) IsEmpty(ctx context.Context) (bool, error) { return repo.isEmpty(ctx, repo.WorkTreeDir) } -func (repo *Local) IsAncestor(_ context.Context, ancestorCommit, descendantCommit string) (bool, error) { - return true_git.IsAncestor(ancestorCommit, descendantCommit, repo.GitDir) +func (repo *Local) IsAncestor(ctx context.Context, ancestorCommit, descendantCommit string) (bool, error) { + return true_git.IsAncestor(ctx, ancestorCommit, descendantCommit, repo.GitDir) } func (repo *Local) RemoteOriginUrl(_ context.Context) (string, error) { diff --git a/pkg/git_repo/remote.go b/pkg/git_repo/remote.go index 4f7e2818fe..8f980dd47a 100644 --- a/pkg/git_repo/remote.go +++ b/pkg/git_repo/remote.go @@ -74,7 +74,7 @@ func (repo *Remote) IsEmpty(ctx context.Context) (bool, error) { } func (repo *Remote) IsAncestor(ctx context.Context, ancestorCommit, descendantCommit string) (bool, error) { - return true_git.IsAncestor(ancestorCommit, descendantCommit, repo.GetClonePath()) + return true_git.IsAncestor(ctx, ancestorCommit, descendantCommit, repo.GetClonePath()) } func (repo *Remote) CloneAndFetch(ctx context.Context) error { @@ -225,8 +225,8 @@ func (repo *Remote) Fetch(ctx context.Context) error { }) } -func (repo *Remote) HeadCommitHash(_ context.Context) (string, error) { - return getHeadCommit(repo.GetClonePath()) +func (repo *Remote) HeadCommitHash(ctx context.Context) (string, error) { + return getHeadCommit(ctx, repo.GetClonePath()) } func (repo *Remote) HeadCommitTime(ctx context.Context) (*time.Time, error) { diff --git a/pkg/true_git/common.go b/pkg/true_git/common.go index 4a5ffe0484..c6087c4d9a 100644 --- a/pkg/true_git/common.go +++ b/pkg/true_git/common.go @@ -1,28 +1,13 @@ package true_git import ( - "bytes" - "context" - "io" - "os/exec" - - "github.com/werf/logboek" + "os" ) -func SetCommandRecordingLiveOutput(ctx context.Context, cmd *exec.Cmd) *bytes.Buffer { - recorder := &bytes.Buffer{} - - if liveGitOutput { - cmd.Stdout = io.MultiWriter(recorder, logboek.Context(ctx).OutStream()) - cmd.Stderr = io.MultiWriter(recorder, logboek.Context(ctx).ErrStream()) - } else { - cmd.Stdout = recorder - cmd.Stderr = recorder - } - - return recorder -} - func getCommonGitOptions() []string { return []string{"-c", "core.autocrlf=false", "-c", "gc.auto=0"} } + +func debug() bool { + return os.Getenv("WERF_DEBUG_TRUE_GIT") == "1" +} diff --git a/pkg/true_git/dot_git.go b/pkg/true_git/dot_git.go index 401c7a7af2..9e9fd7e30b 100644 --- a/pkg/true_git/dot_git.go +++ b/pkg/true_git/dot_git.go @@ -1,9 +1,9 @@ package true_git import ( + "context" "fmt" "os" - "os/exec" "path/filepath" "strings" @@ -12,7 +12,7 @@ import ( "github.com/werf/werf/pkg/util" ) -func UpwardLookupAndVerifyWorkTree(lookupPath string) (bool, string, error) { +func UpwardLookupAndVerifyWorkTree(ctx context.Context, lookupPath string) (bool, string, error) { lookupPath = util.GetAbsoluteFilepath(lookupPath) for { @@ -25,7 +25,7 @@ func UpwardLookupAndVerifyWorkTree(lookupPath string) (bool, string, error) { } } else if err != nil { return false, "", fmt.Errorf("error accessing %q: %s", dotGitPath, err) - } else if isValid, err := IsValidGitDir(dotGitPath); err != nil { + } else if isValid, err := IsValidGitDir(ctx, dotGitPath); err != nil { return false, "", err } else if isValid { return true, lookupPath, nil @@ -37,21 +37,18 @@ func UpwardLookupAndVerifyWorkTree(lookupPath string) (bool, string, error) { return false, "", nil } -func IsValidWorkTree(workTree string) (bool, error) { - return IsValidGitDir(filepath.Join(workTree, git.GitDirName)) +func IsValidWorkTree(ctx context.Context, workTree string) (bool, error) { + return IsValidGitDir(ctx, filepath.Join(workTree, git.GitDirName)) } -func IsValidGitDir(gitDir string) (bool, error) { - gitArgs := append(getCommonGitOptions(), []string{"--git-dir", gitDir, "rev-parse"}...) - - cmd := exec.Command("git", gitArgs...) - - output, err := cmd.CombinedOutput() - if err != nil { - if strings.HasPrefix(string(output), "fatal: not a git repository: ") { +func IsValidGitDir(ctx context.Context, gitDir string) (bool, error) { + detectGitCmd := NewGitCmd(ctx, nil, "--git-dir", gitDir, "rev-parse") + if err := detectGitCmd.Run(ctx); err != nil { + if strings.HasPrefix(detectGitCmd.ErrBuf.String(), "fatal: not a git repository: ") { return false, nil } - return false, fmt.Errorf("%v failed: %s:\n%s", strings.Join(append([]string{"git"}, gitArgs...), " "), err, output) + + return false, fmt.Errorf("git rev parse command failed: %s", err) } return true, nil diff --git a/pkg/true_git/git_cmd.go b/pkg/true_git/git_cmd.go new file mode 100644 index 0000000000..1f210fb161 --- /dev/null +++ b/pkg/true_git/git_cmd.go @@ -0,0 +1,72 @@ +package true_git + +import ( + "bytes" + "context" + "fmt" + "io" + "os/exec" + + "github.com/werf/logboek" +) + +func NewGitCmd(ctx context.Context, opts *GitCmdOptions, cliArgs ...string) GitCmd { + if len(cliArgs) == 0 { + panic("cliArgs required, but not provided") + } + + if opts == nil { + opts = &GitCmdOptions{} + } + + gitCmd := GitCmd{ + OutBuf: &bytes.Buffer{}, + ErrBuf: &bytes.Buffer{}, + OutErrBuf: &bytes.Buffer{}, + } + + gitCmd.Cmd = exec.Command("git", append(getCommonGitOptions(), cliArgs...)...) + + gitCmd.Dir = opts.RepoDir + + stdoutBuffs := []io.Writer{gitCmd.OutBuf, gitCmd.OutErrBuf} + stderrBuffs := []io.Writer{gitCmd.ErrBuf, gitCmd.OutErrBuf} + + if liveGitOutput { + stdoutBuffs = append(stdoutBuffs, logboek.Context(ctx).OutStream()) + stderrBuffs = append(stderrBuffs, logboek.Context(ctx).ErrStream()) + } + + gitCmd.Stdout = io.MultiWriter(stdoutBuffs...) + gitCmd.Stderr = io.MultiWriter(stderrBuffs...) + + return gitCmd +} + +type GitCmdOptions struct { + RepoDir string +} + +type GitCmd struct { + *exec.Cmd + + // We always write to all of these buffs, unlike with exec.Cmd.Stdout(Stderr) + OutBuf *bytes.Buffer + ErrBuf *bytes.Buffer + OutErrBuf *bytes.Buffer +} + +func (c *GitCmd) Run(ctx context.Context) error { + if debug() || liveGitOutput { + logboek.Context(ctx).Debug().LogF("Running command %q\n", c) + } + + switch err := c.Cmd.Run(); err.(type) { + case *exec.ExitError: + return fmt.Errorf("error running command %q: %s\nStdout:\n%s\nStderr:\n%s", c, err, c.OutBuf, c.ErrBuf) + case error: + return fmt.Errorf("error running command %q: %s", c, err) + } + + return nil +} diff --git a/pkg/true_git/git_cmd_test.go b/pkg/true_git/git_cmd_test.go index 8d4e522e4d..fd02c7e004 100644 --- a/pkg/true_git/git_cmd_test.go +++ b/pkg/true_git/git_cmd_test.go @@ -30,11 +30,21 @@ var _ = Describe("Git command", func() { "commit", "--allow-empty", "-m", "Initial commit", ) - Ω(Init(Options{})).Should(Succeed()) + Ω(Init(context.Background(), Options{})).Should(Succeed()) }) - When("git repo contains broken ref", func() { - It("does not ignore git cmd warnings in output due to bug", func() { + When("looking for existent ref", func() { + It("succeeds, returning branch name", func() { + ctx := context.Background() + + output, err := runGitCmd(ctx, []string{"branch", "--list", "master"}, gitRepoPath, runGitCmdOptions{}) + Expect(err).To(Succeed()) + Expect(output.String()).To(ContainSubstring("master")) + }) + }) + + When("looking for non-existent ref", func() { + It("succeeds, ignoring stderr in git output and returning only (empty) stdout", func() { ctx := context.Background() brokenHeadPath := filepath.Join(gitRepoPath, ".git", "refs", "heads", "foo") @@ -42,7 +52,7 @@ var _ = Describe("Git command", func() { output, err := runGitCmd(ctx, []string{"branch", "--list", "no-such-branch"}, gitRepoPath, runGitCmdOptions{}) Expect(err).To(Succeed()) - Expect(output.Len()).NotTo(Equal(0)) + Expect(output.Len()).To(Equal(0)) }) }) }) diff --git a/pkg/true_git/init.go b/pkg/true_git/init.go index a9fd2414b9..7061b6b67c 100644 --- a/pkg/true_git/init.go +++ b/pkg/true_git/init.go @@ -1,11 +1,10 @@ package true_git import ( - "bytes" + "context" "errors" "fmt" "os" - "os/exec" "regexp" "strings" @@ -31,12 +30,12 @@ type Options struct { LiveGitOutput bool } -func Init(opts Options) error { +func Init(ctx context.Context, opts Options) error { liveGitOutput = opts.LiveGitOutput var err error - v, err := getGitCliVersion() + v, err := getGitCliVersion(ctx) if err != nil { return err } @@ -60,16 +59,11 @@ func Init(opts Options) error { return nil } -func getGitCliVersion() (string, error) { - cmd := exec.Command("git", "version") - - var stdout bytes.Buffer - cmd.Stdout = &stdout - - err := cmd.Run() - if err != nil { +func getGitCliVersion(ctx context.Context) (string, error) { + versionCmd := NewGitCmd(ctx, nil, "version") + if err := versionCmd.Run(ctx); err != nil { errMsg := strings.Join([]string{ - fmt.Sprintf("Git version command failed: %s", err), + fmt.Sprintf("git version command failed: %s", err), minGitVersionErrorMsg, forbiddenGitVersionErrorMsg, }, ".\n") @@ -77,9 +71,9 @@ func getGitCliVersion() (string, error) { return "", errors.New(errMsg) } - fullVersionMatch := regexp.MustCompile(`git version ([.0-9]+)`).FindStringSubmatch(stdout.String()) + fullVersionMatch := regexp.MustCompile(`git version ([.0-9]+)`).FindStringSubmatch(versionCmd.OutBuf.String()) if len(fullVersionMatch) < 2 { - return "", errors.New(fmt.Sprintf("unable to parse git version from stdout: %s", stdout.String())) + return "", fmt.Errorf("unable to parse git version from stdout: %s", versionCmd.OutBuf) } fullVersionParts := strings.Split(fullVersionMatch[1], ".") diff --git a/pkg/true_git/merge.go b/pkg/true_git/merge.go index 202e291b00..a38eb1a6f7 100644 --- a/pkg/true_git/merge.go +++ b/pkg/true_git/merge.go @@ -1,12 +1,10 @@ package true_git import ( - "bytes" "context" "fmt" "io/ioutil" "os" - "os/exec" "path/filepath" "strings" ) @@ -34,38 +32,22 @@ func CreateDetachedMergeCommit(ctx context.Context, gitDir, workTreeCacheDir, co if workTreeDir, err := prepareWorkTree(ctx, gitDir, workTreeCacheDir, mergeIntoCommit, opts.HasSubmodules); err != nil { return fmt.Errorf("unable to prepare worktree for commit %v: %s", mergeIntoCommit, err) } else { - var err error - var cmd *exec.Cmd - var output *bytes.Buffer - currentCommitPath := filepath.Join(workTreeCacheDir, "current_commit") if err := os.RemoveAll(currentCommitPath); err != nil { return fmt.Errorf("unable to remove %s: %s", currentCommitPath, err) } - cmd = exec.Command("git", append(getCommonGitOptions(), "-c", "user.email=werf@werf.io", "-c", "user.name=werf", "merge", "--no-edit", "--no-ff", commitToMerge)...) - cmd.Dir = workTreeDir - output = SetCommandRecordingLiveOutput(ctx, cmd) - err = cmd.Run() - if err != nil { - return fmt.Errorf("git merge %q failed: %s\n%s", strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " "), err, output.String()) - } - if debugMerge() { - fmt.Printf("[DEBUG MERGE] %s\n%s\n", strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " "), output) + mergeCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: workTreeDir}, "-c", "user.email=werf@werf.io", "-c", "user.name=werf", "merge", "--no-edit", "--no-ff", commitToMerge) + if err := mergeCmd.Run(ctx); err != nil { + return fmt.Errorf("git merge failed: %s", err) } - cmd = exec.Command("git", append(getCommonGitOptions(), "rev-parse", "HEAD")...) - cmd.Dir = workTreeDir - output = SetCommandRecordingLiveOutput(ctx, cmd) - err = cmd.Run() - if err != nil { - return fmt.Errorf("git merge failed: %s\n%s", err, output.String()) - } - if debugMerge() { - fmt.Printf("[DEBUG MERGE] %s\n%s\n", strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " "), output) + getHeadCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: workTreeDir}, "rev-parse", "HEAD") + if err := getHeadCmd.Run(ctx); err != nil { + return fmt.Errorf("getting HEAD rev during git merge failed: %s", err) } - resCommit = strings.TrimSpace(output.String()) + resCommit = strings.TrimSpace(getHeadCmd.OutBuf.String()) if err := ioutil.WriteFile(currentCommitPath, []byte(resCommit+"\n"), 0o644); err != nil { return fmt.Errorf("unable to write %s: %s", currentCommitPath, err) @@ -79,7 +61,3 @@ func CreateDetachedMergeCommit(ctx context.Context, gitDir, workTreeCacheDir, co return resCommit, nil } - -func debugMerge() bool { - return os.Getenv("WERF_TRUE_GIT_MERGE_DEBUG") == "1" -} diff --git a/pkg/true_git/merge_base.go b/pkg/true_git/merge_base.go index da0f05c51d..57252731b8 100644 --- a/pkg/true_git/merge_base.go +++ b/pkg/true_git/merge_base.go @@ -1,26 +1,27 @@ package true_git import ( + "context" "fmt" "os/exec" "strings" ) -func IsAncestor(ancestorCommit, descendantCommit string, gitDir string) (bool, error) { - gitArgs := append(getCommonGitOptions(), "-C", gitDir, "merge-base", "--is-ancestor", ancestorCommit, descendantCommit) - cmd := exec.Command("git", gitArgs...) - - output, err := cmd.CombinedOutput() +func IsAncestor(ctx context.Context, ancestorCommit, descendantCommit string, gitDir string) (bool, error) { + mergeBaseCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: gitDir}, "merge-base", "--is-ancestor", ancestorCommit, descendantCommit) + err := mergeBaseCmd.Run(ctx) if err != nil { if exitError, ok := err.(*exec.ExitError); ok { if exitError.ExitCode() == 1 { return false, nil } - if exitError.ExitCode() == 128 && strings.HasPrefix(string(output), "fatal: Not a valid commit name ") { + if exitError.ExitCode() == 128 && strings.HasPrefix(mergeBaseCmd.ErrBuf.String(), "fatal: Not a valid commit name ") { return false, nil } } - return false, fmt.Errorf("'git merge-base' failed: %s:\n%s", err, output) + + return false, fmt.Errorf("git merge-base command failed: %s", err) } + return true, nil } diff --git a/pkg/true_git/repository.go b/pkg/true_git/repository.go index 8a18ae2ab0..d8f4afba71 100644 --- a/pkg/true_git/repository.go +++ b/pkg/true_git/repository.go @@ -2,14 +2,13 @@ package true_git import ( "context" - "os/exec" + "fmt" "path/filepath" "strings" "github.com/Masterminds/semver" "github.com/go-git/go-git/v5" - "github.com/werf/logboek" "github.com/werf/werf/pkg/util" ) @@ -27,8 +26,7 @@ type FetchOptions struct { } func Fetch(ctx context.Context, path string, options FetchOptions) error { - command := "git" - commandArgs := append(getCommonGitOptions(), "-C", path, "fetch") + commandArgs := []string{"fetch"} if options.Unshallow { commandArgs = append(commandArgs, "--unshallow") @@ -54,16 +52,12 @@ func Fetch(ctx context.Context, path string, options FetchOptions) error { commandArgs = append(commandArgs, remote, refSpec) } - logboek.Context(ctx).Debug().LogLnDetails(command, strings.Join(commandArgs, " ")) + gitCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: path}, commandArgs...) - cmd := exec.Command(command, commandArgs...) - cmd.Stdout = logboek.Context(ctx).OutStream() - cmd.Stderr = logboek.Context(ctx).ErrStream() - - return cmd.Run() + return gitCmd.Run(ctx) } -func IsShallowClone(path string) (bool, error) { +func IsShallowClone(ctx context.Context, path string) (bool, error) { if gitVersion.LessThan(semver.MustParse("2.15.0")) { exist, err := util.FileExists(filepath.Join(path, ".git", "shallow")) if err != nil { @@ -73,12 +67,10 @@ func IsShallowClone(path string) (bool, error) { return exist, nil } - cmd := exec.Command("git", "-C", path, "rev-parse", "--is-shallow-repository") - - res, err := cmd.Output() - if err != nil { - return false, err + checkShallowCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: path}, "rev-parse", "--is-shallow-repository") + if err := checkShallowCmd.Run(ctx); err != nil { + return false, fmt.Errorf("git shallow repository check command failed: %s", err) } - return strings.TrimSpace(string(res)) == "true", nil + return strings.TrimSpace(checkShallowCmd.OutBuf.String()) == "true", nil } diff --git a/pkg/true_git/service_branch.go b/pkg/true_git/service_branch.go index 5f7a674d8a..2e0292b20f 100644 --- a/pkg/true_git/service_branch.go +++ b/pkg/true_git/service_branch.go @@ -6,7 +6,6 @@ import ( "fmt" "io" "os" - "os/exec" "path/filepath" "strings" "time" @@ -221,31 +220,17 @@ type runGitCmdOptions struct { stdin io.Reader } +// TODO(ilya-lesikov): remove this function, replace with NewGitCmd() func runGitCmd(ctx context.Context, args []string, dir string, opts runGitCmdOptions) (*bytes.Buffer, error) { - allArgs := append(getCommonGitOptions(), args...) - cmd := exec.Command("git", allArgs...) - cmd.Dir = dir + gitCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: dir}, args...) if opts.stdin != nil { - cmd.Stdin = opts.stdin + gitCmd.Stdin = opts.stdin } - output := SetCommandRecordingLiveOutput(ctx, cmd) - - err := cmd.Run() - - cmdWithArgs := strings.Join(append([]string{cmd.Path, "-C " + dir}, cmd.Args[1:]...), " ") - if debug() { - fmt.Printf("[DEBUG] %s\n%s\n", cmdWithArgs, output) - } - - if err != nil { - return nil, err + if err := gitCmd.Run(ctx); err != nil { + return nil, fmt.Errorf("git command run failed: %s", err) } - return output, err -} - -func debug() bool { - return os.Getenv("WERF_DEBUG_TRUE_GIT") == "1" + return gitCmd.OutBuf, nil } diff --git a/pkg/true_git/service_branch_test.go b/pkg/true_git/service_branch_test.go index bb98dbdd48..fb347bd90a 100644 --- a/pkg/true_git/service_branch_test.go +++ b/pkg/true_git/service_branch_test.go @@ -41,7 +41,7 @@ var _ = Describe("SyncSourceWorktreeWithServiceBranch", func() { headCommit = utils.GetHeadCommit(sourceWorkTreeDir) Ω(werf.Init("", "")).Should(Succeed()) - Ω(Init(Options{})).Should(Succeed()) + Ω(Init(context.Background(), Options{})).Should(Succeed()) }) It("no changes", func() { diff --git a/pkg/true_git/show_ref.go b/pkg/true_git/show_ref.go index bab46778cb..1cdc4bbb45 100644 --- a/pkg/true_git/show_ref.go +++ b/pkg/true_git/show_ref.go @@ -1,8 +1,8 @@ package true_git import ( + "context" "fmt" - "os/exec" "strings" ) @@ -24,19 +24,15 @@ type ShowRefResult struct { Refs []RefDescriptor } -func ShowRef(repoDir string) (*ShowRefResult, error) { - gitArgs := append(getCommonGitOptions(), "-C", repoDir, "show-ref", "--head") - - cmd := exec.Command("git", gitArgs...) - - output, err := cmd.CombinedOutput() - if err != nil { - return nil, fmt.Errorf("%v failed: %s:\n%s", strings.Join(append([]string{"git"}, gitArgs...), " "), err, output) +func ShowRef(ctx context.Context, repoDir string) (*ShowRefResult, error) { + headRefCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: repoDir}, "show-ref", "--head") + if err := headRefCmd.Run(ctx); err != nil { + return nil, fmt.Errorf("git get refs from HEAD command failed: %s", err) } res := &ShowRefResult{} - outputLines := strings.Split(string(output), "\n") + outputLines := strings.Split(headRefCmd.OutBuf.String(), "\n") for _, line := range outputLines { parts := strings.SplitN(line, " ", 2) if len(parts) != 2 { diff --git a/pkg/true_git/status/status.go b/pkg/true_git/status/status.go index 4a601b1113..033bb97e83 100644 --- a/pkg/true_git/status/status.go +++ b/pkg/true_git/status/status.go @@ -5,7 +5,6 @@ import ( "context" "fmt" "os" - "os/exec" "strings" "github.com/werf/logboek" @@ -39,26 +38,16 @@ func Status(ctx context.Context, workTreeDir string) (r Result, err error) { func status(ctx context.Context, workTreeDir string) (Result, error) { result := Result{} - args := append([]string{}, "-c", "core.quotePath=false", "status", "--porcelain=v2", "--untracked-files=all", "--no-renames") - cmd := exec.Command("git", args...) - cmd.Dir = workTreeDir - - outputBuffer := true_git.SetCommandRecordingLiveOutput(ctx, cmd) - commandString := strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " ") - detailedErrFunc := func(err error) error { - return fmt.Errorf("%s\n\ncommand: %q\noutput:\n%s", err, commandString, outputBuffer.String()) + statusCmd := true_git.NewGitCmd(ctx, &true_git.GitCmdOptions{RepoDir: workTreeDir}, "-c", "core.quotePath=false", "status", "--porcelain=v2", "--untracked-files=all", "--no-renames") + if err := statusCmd.Run(ctx); err != nil { + return result, fmt.Errorf("git status command failed: %s", err) } - err := cmd.Run() - if debug() { - logboek.Context(ctx).Debug().LogLn("command:", commandString) - logboek.Context(ctx).Debug().LogLn("err:", err) - } - if err != nil { - return result, detailedErrFunc(fmt.Errorf("git command failed: %q", err)) + detailedErrFunc := func(err error) error { + return fmt.Errorf("%s\n\ncommand: %q\noutput:\n%s", err, statusCmd, statusCmd.OutErrBuf) } - scanner := bufio.NewScanner(outputBuffer) + scanner := bufio.NewScanner(statusCmd.OutBuf) for scanner.Scan() { entryLine := scanner.Text() if len(entryLine) == 0 { @@ -86,7 +75,7 @@ func status(ctx context.Context, workTreeDir string) (Result, error) { } } - return result, err + return result, nil } type ordinaryEntry struct { diff --git a/pkg/true_git/submodule.go b/pkg/true_git/submodule.go index 612949352d..669357b159 100644 --- a/pkg/true_git/submodule.go +++ b/pkg/true_git/submodule.go @@ -3,8 +3,6 @@ package true_git import ( "context" "fmt" - "os/exec" - "strings" "github.com/werf/logboek" ) @@ -12,19 +10,9 @@ import ( func syncSubmodules(ctx context.Context, repoDir, workTreeDir string) error { logProcessMsg := fmt.Sprintf("Sync submodules in work tree %q", workTreeDir) return logboek.Context(ctx).Info().LogProcess(logProcessMsg).DoError(func() error { - cmd := exec.Command("git", append(getCommonGitOptions(), "submodule", "sync", "--recursive")...) - - cmd.Dir = workTreeDir // required for `git submodule` to work - - output := SetCommandRecordingLiveOutput(ctx, cmd) - - if debugWorktreeSwitch() { - fmt.Printf("[DEBUG WORKTREE SWITCH] %s\n", strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " ")) - } - - err := cmd.Run() - if err != nil { - return fmt.Errorf("`git submodule sync` failed: %s\n%s", err, output.String()) + submSyncCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: workTreeDir}, "submodule", "sync", "--recursive") + if err := submSyncCmd.Run(ctx); err != nil { + return fmt.Errorf("submodule sync command failed: %s", err) } return nil @@ -34,22 +22,9 @@ func syncSubmodules(ctx context.Context, repoDir, workTreeDir string) error { func updateSubmodules(ctx context.Context, repoDir, workTreeDir string) error { logProcessMsg := fmt.Sprintf("Update submodules in work tree %q", workTreeDir) return logboek.Context(ctx).Info().LogProcess(logProcessMsg).DoError(func() error { - cmd := exec.Command( - "git", append(getCommonGitOptions(), - "submodule", "update", "--checkout", "--force", "--init", "--recursive")..., - ) - - cmd.Dir = workTreeDir // required for `git submodule` to work - - output := SetCommandRecordingLiveOutput(ctx, cmd) - - if debugWorktreeSwitch() { - fmt.Printf("[DEBUG WORKTREE SWITCH] %s\n", strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " ")) - } - - err := cmd.Run() - if err != nil { - return fmt.Errorf("`git submodule update` failed: %s\n%s", err, output.String()) + submUpdateCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: workTreeDir}, "submodule", "update", "--checkout", "--force", "--init", "--recursive") + if err := submUpdateCmd.Run(ctx); err != nil { + return fmt.Errorf("submodule update command failed: %s", err) } return nil diff --git a/pkg/true_git/work_tree.go b/pkg/true_git/work_tree.go index 0ebd93a852..24fdae895b 100644 --- a/pkg/true_git/work_tree.go +++ b/pkg/true_git/work_tree.go @@ -1,12 +1,10 @@ package true_git import ( - "bytes" "context" "fmt" "io/ioutil" "os" - "os/exec" "path/filepath" "strings" "time" @@ -78,7 +76,7 @@ func prepareWorkTree(ctx context.Context, repoDir, workTreeCacheDir string, comm } isWorkTreeRegistered := false - if workTreeList, err := GetWorkTreeList(repoDir); err != nil { + if workTreeList, err := GetWorkTreeList(ctx, repoDir); err != nil { return "", fmt.Errorf("unable to get worktree list for repo %s: %s", repoDir, err) } else { for _, workTreeDesc := range workTreeList { @@ -152,71 +150,31 @@ func prepareWorkTree(ctx context.Context, repoDir, workTreeCacheDir string, comm return workTreeDir, nil } -func debugWorktreeSwitch() bool { - return os.Getenv("WERF_TRUE_GIT_DEBUG_WORKTREE_SWITCH") == "1" -} - func switchWorkTree(ctx context.Context, repoDir, workTreeDir string, commit string, withSubmodules bool) error { - var cmd *exec.Cmd - var output *bytes.Buffer - _, err := os.Stat(workTreeDir) switch { case os.IsNotExist(err): - cmd = exec.Command( - "git", append(getCommonGitOptions(), "-C", repoDir, - "worktree", "add", "--force", "--detach", workTreeDir, commit)..., - ) - - output = SetCommandRecordingLiveOutput(ctx, cmd) - if debugWorktreeSwitch() { - fmt.Printf("[DEBUG WORKTREE SWITCH] %s\n", strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " ")) - } - - if err = cmd.Run(); err != nil { - return fmt.Errorf("git worktree add failed: %s\n%s", err, output.String()) + wtAddCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: repoDir}, "worktree", "add", "--force", "--detach", workTreeDir, commit) + if err = wtAddCmd.Run(ctx); err != nil { + return fmt.Errorf("git worktree add command failed: %s", err) } case err != nil: return fmt.Errorf("error accessing %s: %s", workTreeDir, err) default: - cmd = exec.Command("git", append(getCommonGitOptions(), "checkout", "--force", "--detach", commit)...) - cmd.Dir = workTreeDir - - output = SetCommandRecordingLiveOutput(ctx, cmd) - if debugWorktreeSwitch() { - fmt.Printf("[DEBUG WORKTREE SWITCH] %s\n", strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " ")) - } - - if err = cmd.Run(); err != nil { - return fmt.Errorf("git checkout failed: %s\n%s", err, output.String()) + checkoutCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: workTreeDir}, "checkout", "--force", "--detach", commit) + if err = checkoutCmd.Run(ctx); err != nil { + return fmt.Errorf("git checkout command failed: %s", err) } } - cmd = exec.Command("git", append(getCommonGitOptions(), "reset", "--hard", commit)...) - cmd.Dir = workTreeDir - - output = SetCommandRecordingLiveOutput(ctx, cmd) - if debugWorktreeSwitch() { - fmt.Printf("[DEBUG WORKTREE SWITCH] %s\n", strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " ")) + resetCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: workTreeDir}, "reset", "--hard", commit) + if err = resetCmd.Run(ctx); err != nil { + return fmt.Errorf("git reset command failed: %s", err) } - if err = cmd.Run(); err != nil { - return fmt.Errorf("git reset failed: %s\n%s", err, output.String()) - } - - cmd = exec.Command( - "git", append(getCommonGitOptions(), "--work-tree", workTreeDir, - "clean", "-d", "-f", "-f", "-x")..., - ) - cmd.Dir = workTreeDir - - output = SetCommandRecordingLiveOutput(ctx, cmd) - if debugWorktreeSwitch() { - fmt.Printf("[DEBUG WORKTREE SWITCH] %s\n", strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " ")) - } - - if err = cmd.Run(); err != nil { - return fmt.Errorf("git clean failed: %s\n%s", err, output.String()) + cleanCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: workTreeDir}, "--work-tree", workTreeDir, "clean", "-d", "-f", "-f", "-x") + if err = cleanCmd.Run(ctx); err != nil { + return fmt.Errorf("git worktree clean command failed: %s", err) } if withSubmodules { @@ -228,51 +186,37 @@ func switchWorkTree(ctx context.Context, repoDir, workTreeDir string, commit str return fmt.Errorf("cannot update submodules: %s", err) } - gitArgs := append(getCommonGitOptions(), "--work-tree", workTreeDir, "submodule", "foreach", "--recursive") - gitArgs = append(append(gitArgs, "git"), append(getCommonGitOptions(), "reset", "--hard")...) - - cmd = exec.Command("git", gitArgs...) - cmd.Dir = workTreeDir // required for `git submodule` to work - - output = SetCommandRecordingLiveOutput(ctx, cmd) - if debugWorktreeSwitch() { - fmt.Printf("[DEBUG WORKTREE SWITCH] %s\n", strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " ")) + submResetArgs := []string{ + "--work-tree", workTreeDir, "submodule", "foreach", "--recursive", } + submResetArgs = append(submResetArgs, append([]string{"git"}, append(getCommonGitOptions(), "reset", "--hard")...)...) - if err = cmd.Run(); err != nil { - return fmt.Errorf("git submodules reset failed: %s\n%s", err, output.String()) + submResetCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: workTreeDir}, submResetArgs...) + if err = submResetCmd.Run(ctx); err != nil { + return fmt.Errorf("git submodules reset commands failed: %s", err) } - gitArgs = append(getCommonGitOptions(), "--work-tree", workTreeDir, "submodule", "foreach", "--recursive") - gitArgs = append(append(gitArgs, "git"), append(getCommonGitOptions(), "clean", "-d", "-f", "-f", "-x")...) - - cmd = exec.Command("git", gitArgs...) - cmd.Dir = workTreeDir // required for `git submodule` to work - - output = SetCommandRecordingLiveOutput(ctx, cmd) - if debugWorktreeSwitch() { - fmt.Printf("[DEBUG WORKTREE SWITCH] %s\n", strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " ")) + submCleanArgs := []string{ + "--work-tree", workTreeDir, "submodule", "foreach", "--recursive", } + submCleanArgs = append(submCleanArgs, append([]string{"git"}, append(getCommonGitOptions(), "clean", "-d", "-f", "-f", "-x")...)...) - if err = cmd.Run(); err != nil { - return fmt.Errorf("git submodules clean failed: %s\n%s", err, output.String()) + submCleanCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: workTreeDir}, submCleanArgs...) + if err = submCleanCmd.Run(ctx); err != nil { + return fmt.Errorf("git submodules clean commands failed: %s", err) } } return nil } -func ResolveRepoDir(repoDir string) (string, error) { - gitArgs := append(getCommonGitOptions(), "--git-dir", repoDir, "rev-parse", "--git-dir") - - cmd := exec.Command("git", gitArgs...) - - output, err := cmd.CombinedOutput() - if err != nil { - return "", fmt.Errorf("%q failed (%s): %s:\n%s", strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " "), repoDir, err, output) +func ResolveRepoDir(ctx context.Context, repoDir string) (string, error) { + revParseCmd := NewGitCmd(ctx, nil, "--git-dir", repoDir, "rev-parse", "--git-dir") + if err := revParseCmd.Run(ctx); err != nil { + return "", fmt.Errorf("git parse git-dir command failed: %s", err) } - return strings.TrimSpace(string(output)), nil + return strings.TrimSpace(revParseCmd.OutBuf.String()), nil } type WorktreeDescriptor struct { @@ -281,18 +225,15 @@ type WorktreeDescriptor struct { Branch string } -func GetWorkTreeList(repoDir string) ([]WorktreeDescriptor, error) { - gitArgs := append(getCommonGitOptions(), "-C", repoDir, "worktree", "list", "--porcelain") - cmd := exec.Command("git", gitArgs...) - - output, err := cmd.CombinedOutput() - if err != nil { - return nil, fmt.Errorf("%q failed (%s): %s:\n%s", strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " "), repoDir, err, output) +func GetWorkTreeList(ctx context.Context, repoDir string) ([]WorktreeDescriptor, error) { + wtListCmd := NewGitCmd(ctx, &GitCmdOptions{RepoDir: repoDir}, "worktree", "list", "--porcelain") + if err := wtListCmd.Run(ctx); err != nil { + return nil, fmt.Errorf("git worktree list command failed: %s", err) } var worktreeDesc *WorktreeDescriptor var res []WorktreeDescriptor - for _, line := range strings.Split(string(output), "\n") { + for _, line := range strings.Split(wtListCmd.OutBuf.String(), "\n") { if line == "" && worktreeDesc == nil { continue } else if worktreeDesc == nil {