func (o *Options) MergeChanges(reqs *jxcore.Requirements) error {
	err := mergo.Merge(o.requirements, reqs.Spec, mergo.WithOverride)
	if err != nil {
		return errors.Wrap(err, "error merging requirements")
	}
	if reqs.Spec.Ingress.Domain != "" {
		o.requirements.Ingress.Domain = reqs.Spec.Ingress.Domain
	}
	return nil
}
MergeChanges merges changes from the given requirements into the source
package merge
import (
	"context"
	"fmt"
	"io/ioutil"
	"path/filepath"
	"github.com/imdario/mergo"
	"github.com/jenkins-x-plugins/jx-gitops/pkg/rootcmd"
	jxcore "github.com/jenkins-x/jx-api/v4/pkg/apis/core/v4beta1"
	"github.com/jenkins-x/jx-helpers/v3/pkg/cobras/templates"
	"github.com/jenkins-x/jx-helpers/v3/pkg/files"
	"github.com/jenkins-x/jx-helpers/v3/pkg/kube"
	"github.com/jenkins-x/jx-helpers/v3/pkg/termcolor"
	"github.com/jenkins-x/jx-logging/v3/pkg/log"
	"github.com/pkg/errors"
	"github.com/spf13/cobra"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
)
const (
	ConfigMapNamespace = "default"
	ConfigMapName = "terraform-jx-requirements"
	ConfigMapKey = "jx-requirements.yml"
)
var (
	cmdLong = templates.LongDesc(`
		Merges values from the given file to the local jx-requirements.yml file
This lets you take requirements from, say, the output of a terraform plan and merge with any other changes inside your GitOps repository
`)
	cmdExample = templates.Examples(`
		# merge requirements from a file
		%s requirements merge -f /tmp/jx-requirements.yml
		# merge requirements from a ConfigMap called 'terraform-jx-requirements' in the default namespace
		%s requirements merge 
	`)
)
type Options struct {
	Dir                  string
	File                 string
	Namespace            string
	ConfigMapName        string
	KubeClient           kubernetes.Interface
	requirements         *jxcore.RequirementsConfig
	requirementsFileName string
}
func NewCmdRequirementsMerge() (*cobra.Command, *Options) {
	o := &Options{}
	cmd := &cobra.Command{
		Use:     "merge",
		Short:   "Merges values from the given file to the local jx-requirements.yml file",
		Long:    cmdLong,
		Example: fmt.Sprintf(cmdExample, rootcmd.BinaryName, rootcmd.BinaryName),
		RunE: func(cmd *cobra.Command, args []string) error {
			return o.Run()
		},
	}
	cmd.Flags().StringVarP(&o.Dir, "dir", "d", ".", "the source directory to merge changes into")
	cmd.Flags().StringVarP(&o.File, "file", "f", "", "the requirements file to merge into the source directory")
	cmd.Flags().StringVarP(&o.Namespace, "namespace", "", ConfigMapNamespace, "the namespace used to find the ConfigMap if using the ConfigMap mode")
	cmd.Flags().StringVarP(&o.ConfigMapName, "configmap", "c", ConfigMapName, "the name of the ConfigMap to find the requirements to merge if not specifying a requirements file via --file")
	return cmd, o
}
func (o *Options) Run() error {
	var err error
	if o.File == "" {
		o.File, err = o.loadRequirementsFileFromConfigMap()
		if err != nil {
			return errors.Wrapf(err, "failed to load the 'jx-requirements.yml' from the ConfigMap")
		}
		if o.File == "" {
			return nil
		}
	}
	var requirementsResource *jxcore.Requirements
	requirementsResource, o.requirementsFileName, err = jxcore.LoadRequirementsConfig(o.Dir, false)
	if err != nil {
		return errors.Wrapf(err, "failed to load requirements in dir %s", o.Dir)
	}
	o.requirements = &requirementsResource.Spec
	if o.requirementsFileName == "" {
		o.requirementsFileName = filepath.Join(o.Dir, jxcore.RequirementsConfigFileName)
	}
	requirementChanges, err := jxcore.LoadRequirementsConfigFileNoDefaults(o.File, false)
	if err != nil {
		return errors.Wrapf(err, "failed to load requirement changes from file: %s", o.File)
	}
	if requirementChanges != nil {
		requirementChanges.Spec.Environments = nil
	}
	exists := false
	if o.requirements != nil {
		exists, err = files.FileExists(o.requirementsFileName)
		if err != nil {
			return errors.Wrapf(err, "failed to check if file exists %s", o.requirementsFileName)
		}
	}
	if exists {
		err = o.MergeChanges(requirementChanges)
		if err != nil {
			return errors.Wrapf(err, "failed to merge changes from %s", o.File)
		}
	} else {
		o.requirements = &requirementChanges.Spec
	}
	err = requirementsResource.SaveConfig(o.requirementsFileName)
	if err != nil {
		return errors.Wrapf(err, "failed to save file %s", o.requirementsFileName)
	}
	log.Logger().Infof("saved file %s", termcolor.ColorInfo(o.requirementsFileName))
	return nil
}