You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: releaser_service.go
    path of file: ./repos/pipeline/internal/helm/helmadapter
    
    the code of the file until where you have to start completion: // Copyright Â© 2020 Banzai Cloud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package helmadapter

import (
	"context"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"time"

	"emperror.dev/errors"
	"github.com/mitchellh/mapstructure"
	"gopkg.in/yaml.v2"
	"helm.sh/helm/v3/pkg/action"
	"helm.sh/helm/v3/pkg/chart"
	"helm.sh/helm/v3/pkg/chart/loader"
	"helm.sh/helm/v3/pkg/cli"
	"helm.sh/helm/v3/pkg/cli/values"
	"helm.sh/helm/v3/pkg/downloader"
	"helm.sh/helm/v3/pkg/getter"
	"helm.sh/helm/v3/pkg/release"
	"helm.sh/helm/v3/pkg/storage/driver"
	v1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/meta"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/cli-runtime/pkg/genericclioptions"
	"k8s.io/client-go/discovery"
	"k8s.io/client-go/discovery/cached/disk"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/restmapper"
	"k8s.io/client-go/tools/clientcmd"
	clientcmdapi "k8s.io/client-go/tools/clientcmd/api"

	"github.com/banzaicloud/pipeline/internal/helm"
	"github.com/banzaicloud/pipeline/pkg/k8sclient"
)

// Components in charge for implementing release helm related operations.
type releaser struct {
	logger Logger
}

func NewReleaser(logger Logger) helm.Releaser {
	return releaser{
		logger: logger,
	}
}

func 
    
func (r releaser) Install(ctx context.Context, helmEnv helm.HelmEnv, kubeConfig helm.KubeConfigBytes, releaseInput helm.Release, options helm.Options) (helm.Release, error) {
	// customize the settings passed forward
	envSettings := r.processEnvSettings(helmEnv)

	ns := "default"
	if options.Namespace != "" {
		ns = options.Namespace
	}

	// component processing the kubeconfig
	restClientGetter := NewCustomGetter(ns, kubeConfig, helmEnv.GetCacheDir(), r.logger)

	actionConfig, err := r.getActionConfiguration(restClientGetter, ns)
	if err != nil {
		return helm.Release{}, errors.WrapIf(err, "failed to get  action configuration")
	}

	installAction := action.NewInstall(actionConfig)
	installAction.Namespace = ns
	// TODO the generate name is already coded into the options; revisit this after h2 is removed
	if releaseInput.ReleaseName == "" {
		installAction.GenerateName = true
	}

	name, chartRef, err := installAction.NameAndChart(releaseInput.NameAndChartSlice())
	if err != nil {
		return helm.Release{}, errors.WrapIf(err, "failed to get  name  and chart")
	}
	installAction.ReleaseName = name
	installAction.Wait = options.Wait
	installAction.Timeout = time.Minute * 5
	installAction.Version = releaseInput.Version
	installAction.SkipCRDs = options.SkipCRDs

	cp, err := installAction.ChartPathOptions.LocateChart(chartRef, envSettings)
	if err != nil {
		return helm.Release{}, errors.WrapIf(err, "failed to locate chart")
	}

	p := getter.All(envSettings)

	// Check chart dependencies to make sure all are present in /charts
	chartRequested, err := loader.Load(cp)
	if err != nil {
		return helm.Release{}, errors.WrapIf(err, "failed to load chart")
	}

	validInstallableChart, err := isChartInstallable(chartRequested)
	if !validInstallableChart {
		return helm.Release{}, errors.WrapIf(err, "chart is not installable")
	}

	if chartRequested.Metadata.Deprecated {
		r.logger.Warn(" This chart is deprecated")
	}

	if req := chartRequested.Metadata.Dependencies; req != nil {
		// If CheckDependencies returns an error, we have unfulfilled dependencies.
		// As of Helm 2.4.0, this is treated as a stopping condition:
		// https://github.com/helm/helm/issues/2209
		if err := action.CheckDependencies(chartRequested, req); err != nil {
			if installAction.DependencyUpdate {
				man := &downloader.Manager{
					Out:              os.Stdout,
					ChartPath:        cp,
					Keyring:          installAction.ChartPathOptions.Keyring,
					SkipUpdate:       false,
					Getters:          p,
					RepositoryConfig: envSettings.RepositoryConfig,
					RepositoryCache:  envSettings.RepositoryCache,
				}
				if err := man.Update(); err != nil {
					return helm.Release{}, errors.WrapIf(err, "failed to update chart dependencies")
				}
			} else {
				return helm.Release{}, errors.WrapIf(err, "failed to check chart dependencies")
			}
		}
	}

	clientSet, err := k8sclient.NewClientFromKubeConfigWithTimeout(kubeConfig, time.Second*10)
	if err != nil {
		return helm.Release{}, errors.WrapIf(err, "failed to create kubernetes client")
	}

	namespaces, err := clientSet.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
	if err != nil {
		return helm.Release{}, errors.WrapIf(err, "failed to list kubernetes namespaces")
	}

	foundNs := false
	for _, ns := range namespaces.Items {
		if ns.Name == installAction.Namespace {
			foundNs = true
		}
	}

	if !foundNs {
		if _, err := clientSet.CoreV1().Namespaces().Create(ctx, &v1.Namespace{
			ObjectMeta: metav1.ObjectMeta{
				Name: installAction.Namespace,
			},
		},
			metav1.CreateOptions{},
		); err != nil {
			return helm.Release{}, errors.WrapIf(err, "failed to create release namespace")
		}
	}

	releasePtr, err := installAction.Run(chartRequested, releaseInput.Values)
	if err != nil {
		return helm.Release{}, errors.WrapIf(err, "failed to install chart")
	}

	return r.adaptReleasePtr(releasePtr), nil
}