DodoApp: Commit Helm charts to dodo branch

Change-Id: I98c528b37b2e3cb1765944792e4057e3ccbee4c9
diff --git a/core/installer/app_manager.go b/core/installer/app_manager.go
index cad18eb..d3b64ab 100644
--- a/core/installer/app_manager.go
+++ b/core/installer/app_manager.go
@@ -299,13 +299,17 @@
 		i(&o)
 	}
 	dopts := []soft.DoOption{}
+	// NOTE(gio): Expects caller to have pulled already
+	dopts = append(dopts, soft.WithNoPull())
 	if o.Branch != "" {
-		dopts = append(dopts, soft.WithForce())
 		dopts = append(dopts, soft.WithCommitToBranch(o.Branch))
 	}
 	if o.NoPublish {
 		dopts = append(dopts, soft.WithNoCommit())
 	}
+	if o.Force {
+		dopts = append(dopts, soft.WithForce())
+	}
 	return ReleaseResources{}, repo.Do(func(r soft.RepoFS) (string, error) {
 		if err := r.RemoveDir(appDir); err != nil {
 			return "", err
@@ -432,17 +436,11 @@
 			return ReleaseResources{}, err
 		}
 	}
-	var localCharts map[string]helmv2.HelmChartTemplateSpec
-	if err := m.repoIO.Do(func(rfs soft.RepoFS) (string, error) {
-		charts, err := pullHelmCharts(m.hf, rendered.HelmCharts, rfs, "/helm-charts")
-		if err != nil {
-			return "", err
-		}
-		localCharts = generateLocalCharts(lg, charts)
-		return "pull helm charts", nil
-	}); err != nil {
+	charts, err := pullHelmCharts(m.hf, rendered.HelmCharts, m.repoIO, "/helm-charts")
+	if err != nil {
 		return ReleaseResources{}, err
 	}
+	localCharts := generateLocalCharts(lg, charts)
 	if o.FetchContainerImages {
 		release.ImageRegistry = imageRegistry
 	}
@@ -597,6 +595,7 @@
 	Branch               string
 	LG                   LocalChartGenerator
 	FetchContainerImages bool
+	Force                bool
 }
 
 type InstallOption func(*installOptions)
@@ -613,6 +612,12 @@
 	}
 }
 
+func WithForce() InstallOption {
+	return func(o *installOptions) {
+		o.Force = true
+	}
+}
+
 func WithLocalChartGenerator(lg LocalChartGenerator) InstallOption {
 	return func(o *installOptions) {
 		o.LG = lg
@@ -711,17 +716,11 @@
 	if err != nil {
 		return ReleaseResources{}, err
 	}
-	var localCharts map[string]helmv2.HelmChartTemplateSpec
-	if err := m.repoIO.Do(func(rfs soft.RepoFS) (string, error) {
-		charts, err := pullHelmCharts(m.hf, rendered.HelmCharts, rfs, "/helm-charts")
-		if err != nil {
-			return "", err
-		}
-		localCharts = generateLocalCharts(m.lg, charts)
-		return "pull helm charts", nil
-	}); err != nil {
+	charts, err := pullHelmCharts(m.hf, rendered.HelmCharts, m.repoIO, "/helm-charts")
+	if err != nil {
 		return ReleaseResources{}, err
 	}
+	localCharts := generateLocalCharts(m.lg, charts)
 	rendered, err = app.Render(release, infra, values, localCharts)
 	if err != nil {
 		return ReleaseResources{}, err
diff --git a/core/installer/soft/repoio.go b/core/installer/soft/repoio.go
index 7df75dc..dcf897d 100644
--- a/core/installer/soft/repoio.go
+++ b/core/installer/soft/repoio.go
@@ -36,6 +36,7 @@
 type DoFn func(r RepoFS) (string, error)
 
 type doOptions struct {
+	NoPull   bool
 	NoCommit bool
 	Force    bool
 	ToBranch string
@@ -43,6 +44,12 @@
 
 type DoOption func(*doOptions)
 
+func WithNoPull() DoOption {
+	return func(o *doOptions) {
+		o.NoPull = true
+	}
+}
+
 func WithNoCommit() DoOption {
 	return func(o *doOptions) {
 		o.NoCommit = true
@@ -219,13 +226,15 @@
 func (r *repoIO) Do(op DoFn, opts ...DoOption) error {
 	r.l.Lock()
 	defer r.l.Unlock()
-	if err := r.pullWithoutLock(); err != nil {
-		return err
-	}
 	o := &doOptions{}
 	for _, i := range opts {
 		i(o)
 	}
+	if !o.NoPull {
+		if err := r.pullWithoutLock(); err != nil {
+			return err
+		}
+	}
 	if msg, err := op(r); err != nil {
 		return err
 	} else {
diff --git a/core/installer/welcome/dodo_app.go b/core/installer/welcome/dodo_app.go
index 7ca9198..39d3a03 100644
--- a/core/installer/welcome/dodo_app.go
+++ b/core/installer/welcome/dodo_app.go
@@ -134,10 +134,20 @@
 		return err
 	}
 	lg := installer.GitRepositoryLocalChartGenerator{"app", namespace}
-	if _, err := m.Install(app, "app", "/.dodo/app", namespace, map[string]any{
-		"repoAddr":      repo.FullAddress(),
-		"sshPrivateKey": sshKey,
-	}, installer.WithConfig(env), installer.WithBranch("dodo"), installer.WithLocalChartGenerator(lg)); err != nil {
+	if _, err := m.Install(
+		app,
+		"app",
+		"/.dodo/app",
+		namespace,
+		map[string]any{
+			"repoAddr":      repo.FullAddress(),
+			"sshPrivateKey": sshKey,
+		},
+		installer.WithConfig(env),
+		installer.WithLocalChartGenerator(lg),
+		installer.WithBranch("dodo"),
+		installer.WithForce(),
+	); err != nil {
 		return err
 	}
 	return nil