From b2570ef1a07740b16525af19105b4d52eaed2861 Mon Sep 17 00:00:00 2001 From: jackgr Date: Tue, 22 Mar 2016 13:16:18 -0700 Subject: [PATCH] Make Repo struct public --- pkg/repo/filebased_credential_provider.go | 4 +- .../filebased_credential_provider_test.go | 2 +- pkg/repo/gcs_repo.go | 28 ++++++------ pkg/repo/gcs_repo_test.go | 2 +- pkg/repo/inmem_credential_provider.go | 2 +- pkg/repo/inmem_credential_provider_test.go | 4 +- pkg/repo/inmem_repo_service.go | 18 ++++---- pkg/repo/repo.go | 39 +++++++--------- pkg/repo/repoprovider.go | 44 +++++++++--------- pkg/repo/repoprovider_test.go | 4 +- pkg/repo/secrets_credential_provider.go | 2 +- pkg/repo/types.go | 45 +++++++++++-------- 12 files changed, 97 insertions(+), 97 deletions(-) diff --git a/pkg/repo/filebased_credential_provider.go b/pkg/repo/filebased_credential_provider.go index 834511d1a..3a1a71795 100644 --- a/pkg/repo/filebased_credential_provider.go +++ b/pkg/repo/filebased_credential_provider.go @@ -27,7 +27,7 @@ import ( // FilebasedCredentialProvider provides credentials for registries. type FilebasedCredentialProvider struct { // Actual backing store - backingCredentialProvider CredentialProvider + backingCredentialProvider ICredentialProvider } // NamedRepoCredential associates a name with a RepoCredential. @@ -37,7 +37,7 @@ type NamedRepoCredential struct { } // NewFilebasedCredentialProvider creates a file based credential provider. -func NewFilebasedCredentialProvider(filename string) (CredentialProvider, error) { +func NewFilebasedCredentialProvider(filename string) (ICredentialProvider, error) { icp := NewInmemCredentialProvider() log.Printf("Using credentials file %s", filename) c, err := readCredentialsFile(filename) diff --git a/pkg/repo/filebased_credential_provider_test.go b/pkg/repo/filebased_credential_provider_test.go index e10347b20..f79629b92 100644 --- a/pkg/repo/filebased_credential_provider_test.go +++ b/pkg/repo/filebased_credential_provider_test.go @@ -47,7 +47,7 @@ func TestSetAndGetBasicAuthFilebased(t *testing.T) { testGetCredential(t, cp, tc) } -func getProvider(t *testing.T) CredentialProvider { +func getProvider(t *testing.T) ICredentialProvider { cp, err := NewFilebasedCredentialProvider(filename) if err != nil { t.Fatalf("cannot create a new provider from file %s: %s", filename, err) diff --git a/pkg/repo/gcs_repo.go b/pkg/repo/gcs_repo.go index 33075704e..ae503b5d9 100644 --- a/pkg/repo/gcs_repo.go +++ b/pkg/repo/gcs_repo.go @@ -53,21 +53,21 @@ const ( GCSPublicRepoBucket = GCSPublicRepoName ) -// gcsRepo implements the ObjectStorageRepo interface for Google Cloud Storage. -type gcsRepo struct { - repo +// GCSRepo implements the IStorageRepo interface for Google Cloud Storage. +type GCSRepo struct { + Repo bucket string httpClient *http.Client service *storage.Service } -// NewPublicGCSRepo creates a new an ObjectStorageRepo for the public GCS repository. -func NewPublicGCSRepo(httpClient *http.Client) (ObjectStorageRepo, error) { +// NewPublicGCSRepo creates a new an IStorageRepo for the public GCS repository. +func NewPublicGCSRepo(httpClient *http.Client) (IStorageRepo, error) { return NewGCSRepo(GCSPublicRepoName, GCSPublicRepoURL, "", nil) } -// NewGCSRepo creates a new ObjectStorageRepo for a given GCS repository. -func NewGCSRepo(name, URL, credentialName string, httpClient *http.Client) (ObjectStorageRepo, error) { +// NewGCSRepo creates a new IStorageRepo for a given GCS repository. +func NewGCSRepo(name, URL, credentialName string, httpClient *http.Client) (IStorageRepo, error) { r, err := newRepo(name, URL, credentialName, GCSRepoFormat, GCSRepoType) if err != nil { return nil, err @@ -76,7 +76,7 @@ func NewGCSRepo(name, URL, credentialName string, httpClient *http.Client) (Obje return newGCSRepo(r, httpClient) } -func newGCSRepo(r *repo, httpClient *http.Client) (*gcsRepo, error) { +func newGCSRepo(r *Repo, httpClient *http.Client) (*GCSRepo, error) { URL := r.GetURL() m := GCSRepoURLMatcher.FindStringSubmatch(URL) if len(m) != 2 { @@ -96,8 +96,8 @@ func newGCSRepo(r *repo, httpClient *http.Client) (*gcsRepo, error) { return nil, fmt.Errorf("cannot create storage service for %s: %s", URL, err) } - gcsr := &gcsRepo{ - repo: *r, + gcsr := &GCSRepo{ + Repo: *r, httpClient: httpClient, service: gcs, bucket: m[1], @@ -117,7 +117,7 @@ func validateRepoType(repoType RepoType) error { // ListCharts lists charts in this chart repository whose string values conform to the // supplied regular expression, or all charts, if the regular expression is nil. -func (g *gcsRepo) ListCharts(regex *regexp.Regexp) ([]string, error) { +func (g *GCSRepo) ListCharts(regex *regexp.Regexp) ([]string, error) { charts := []string{} // List all objects in a bucket using pagination @@ -155,7 +155,7 @@ func (g *gcsRepo) ListCharts(regex *regexp.Regexp) ([]string, error) { } // GetChart retrieves, unpacks and returns a chart by name. -func (g *gcsRepo) GetChart(name string) (*chart.Chart, error) { +func (g *GCSRepo) GetChart(name string) (*chart.Chart, error) { // Charts should be named bucket/chart-X.Y.Z.tgz, so check that the name matches if !ChartNameMatcher.MatchString(name) { return nil, fmt.Errorf("name must be of the form -.tgz, was %s", name) @@ -184,11 +184,11 @@ func (g *gcsRepo) GetChart(name string) (*chart.Chart, error) { } // GetBucket returns the repository bucket. -func (g *gcsRepo) GetBucket() string { +func (g *GCSRepo) GetBucket() string { return g.bucket } // Do performs an HTTP operation on the receiver's httpClient. -func (g *gcsRepo) Do(req *http.Request) (resp *http.Response, err error) { +func (g *GCSRepo) Do(req *http.Request) (resp *http.Response, err error) { return g.httpClient.Do(req) } diff --git a/pkg/repo/gcs_repo_test.go b/pkg/repo/gcs_repo_test.go index 457024965..163d662f5 100644 --- a/pkg/repo/gcs_repo_test.go +++ b/pkg/repo/gcs_repo_test.go @@ -125,7 +125,7 @@ func TestGetChartWithInvalidName(t *testing.T) { } } -func getTestRepo(t *testing.T) ObjectStorageRepo { +func getTestRepo(t *testing.T) IStorageRepo { tr, err := NewGCSRepo(TestRepoName, TestRepoURL, TestRepoCredentialName, nil) if err != nil { t.Fatal(err) diff --git a/pkg/repo/inmem_credential_provider.go b/pkg/repo/inmem_credential_provider.go index 453966b4a..55805878b 100644 --- a/pkg/repo/inmem_credential_provider.go +++ b/pkg/repo/inmem_credential_provider.go @@ -28,7 +28,7 @@ type InmemCredentialProvider struct { } // NewInmemCredentialProvider creates a new memory based credential provider. -func NewInmemCredentialProvider() CredentialProvider { +func NewInmemCredentialProvider() ICredentialProvider { return &InmemCredentialProvider{credentials: make(map[string]*RepoCredential)} } diff --git a/pkg/repo/inmem_credential_provider_test.go b/pkg/repo/inmem_credential_provider_test.go index 2c7d9e639..d75d44b0e 100644 --- a/pkg/repo/inmem_credential_provider_test.go +++ b/pkg/repo/inmem_credential_provider_test.go @@ -32,7 +32,7 @@ func createMissingError(name string) error { return fmt.Errorf("no such credential: %s", name) } -func testGetCredential(t *testing.T, cp CredentialProvider, tc *testCase) { +func testGetCredential(t *testing.T, cp ICredentialProvider, tc *testCase) { actual, actualErr := cp.GetCredential(tc.name) if !reflect.DeepEqual(actual, tc.exp) { t.Fatalf("test case %s failed: want: %#v, have: %#v", tc.name, tc.exp, actual) @@ -43,7 +43,7 @@ func testGetCredential(t *testing.T, cp CredentialProvider, tc *testCase) { } } -func verifySetAndGetCredential(t *testing.T, cp CredentialProvider, tc *testCase) { +func verifySetAndGetCredential(t *testing.T, cp ICredentialProvider, tc *testCase) { err := cp.SetCredential(tc.name, tc.exp) if err != nil { t.Fatalf("test case %s failed: cannot set credential: %v", tc.name, err) diff --git a/pkg/repo/inmem_repo_service.go b/pkg/repo/inmem_repo_service.go index b1abcc1d1..a987dd467 100644 --- a/pkg/repo/inmem_repo_service.go +++ b/pkg/repo/inmem_repo_service.go @@ -24,13 +24,13 @@ import ( type inmemRepoService struct { sync.RWMutex - repositories map[string]Repo + repositories map[string]IRepo } // NewInmemRepoService returns a new memory based repository service. -func NewInmemRepoService() Service { +func NewInmemRepoService() IRepoService { rs := &inmemRepoService{ - repositories: make(map[string]Repo), + repositories: make(map[string]IRepo), } r, err := NewPublicGCSRepo(nil) @@ -42,11 +42,11 @@ func NewInmemRepoService() Service { } // List returns the list of all known chart repositories -func (rs *inmemRepoService) List() ([]Repo, error) { +func (rs *inmemRepoService) List() ([]IRepo, error) { rs.RLock() defer rs.RUnlock() - ret := []Repo{} + ret := []IRepo{} for _, r := range rs.repositories { ret = append(ret, r) } @@ -55,7 +55,7 @@ func (rs *inmemRepoService) List() ([]Repo, error) { } // Create adds a known repository to the list -func (rs *inmemRepoService) Create(repository Repo) error { +func (rs *inmemRepoService) Create(repository IRepo) error { rs.Lock() defer rs.Unlock() @@ -70,7 +70,7 @@ func (rs *inmemRepoService) Create(repository Repo) error { } // Get returns the repository with the given name -func (rs *inmemRepoService) Get(name string) (Repo, error) { +func (rs *inmemRepoService) Get(name string) (IRepo, error) { rs.RLock() defer rs.RUnlock() @@ -83,11 +83,11 @@ func (rs *inmemRepoService) Get(name string) (Repo, error) { } // GetByURL returns the repository that backs the given URL -func (rs *inmemRepoService) GetByURL(URL string) (Repo, error) { +func (rs *inmemRepoService) GetByURL(URL string) (IRepo, error) { rs.RLock() defer rs.RUnlock() - var found Repo + var found IRepo for _, r := range rs.repositories { rURL := r.GetURL() if strings.HasPrefix(URL, rURL) { diff --git a/pkg/repo/repo.go b/pkg/repo/repo.go index 8e3aee3ae..27e409fd4 100644 --- a/pkg/repo/repo.go +++ b/pkg/repo/repo.go @@ -21,21 +21,12 @@ import ( "net/url" ) -// repo describes a repository -type repo struct { - Name string `json:"name"` // Friendly name for this repository - URL string `json:"url"` // URL to the root of this repository - CredentialName string `json:"credentialname"` // Credential name used to access this repository - Format RepoFormat `json:"format"` // Format of this repository - Type RepoType `json:"type"` // Technology implementing this repository -} - -// NewRepo takes params and returns a Repo -func NewRepo(name, URL, credentialName, repoFormat, repoType string) (Repo, error) { +// NewRepo takes params and returns a IRepo +func NewRepo(name, URL, credentialName, repoFormat, repoType string) (IRepo, error) { return newRepo(name, URL, credentialName, RepoFormat(repoFormat), RepoType(repoType)) } -func newRepo(name, URL, credentialName string, repoFormat RepoFormat, repoType RepoType) (*repo, error) { +func newRepo(name, URL, credentialName string, repoFormat RepoFormat, repoType RepoType) (*Repo, error) { if name == "" { return nil, fmt.Errorf("name must not be empty") } @@ -53,7 +44,7 @@ func newRepo(name, URL, credentialName string, repoFormat RepoFormat, repoType R return nil, err } - r := &repo{ + r := &Repo{ Name: name, Type: repoType, URL: URL, @@ -75,39 +66,39 @@ func validateRepoFormat(repoFormat RepoFormat) error { } // GetName returns the friendly name of this repository. -func (r *repo) GetName() string { +func (r *Repo) GetName() string { return r.Name } // GetType returns the technology implementing this repository. -func (r *repo) GetType() RepoType { +func (r *Repo) GetType() RepoType { return r.Type } // GetURL returns the URL to the root of this repository. -func (r *repo) GetURL() string { +func (r *Repo) GetURL() string { return r.URL } // GetFormat returns the format of this repository. -func (r *repo) GetFormat() RepoFormat { +func (r *Repo) GetFormat() RepoFormat { return r.Format } // GetCredentialName returns the credential name used to access this repository. -func (r *repo) GetCredentialName() string { +func (r *Repo) GetCredentialName() string { return r.CredentialName } -func validateRepo(tr Repo, wantName, wantURL, wantCredentialName string, wantFormat RepoFormat, wantType RepoType) error { +func validateRepo(tr IRepo, wantName, wantURL, wantCredentialName string, wantFormat RepoFormat, wantType RepoType) error { haveName := tr.GetName() if haveName != wantName { - return fmt.Errorf("unexpected repo name; want: %s, have %s", wantName, haveName) + return fmt.Errorf("unexpected repository name; want: %s, have %s", wantName, haveName) } haveURL := tr.GetURL() if haveURL != wantURL { - return fmt.Errorf("unexpected repo url; want: %s, have %s", wantURL, haveURL) + return fmt.Errorf("unexpected repository url; want: %s, have %s", wantURL, haveURL) } haveCredentialName := tr.GetCredentialName() @@ -116,17 +107,17 @@ func validateRepo(tr Repo, wantName, wantURL, wantCredentialName string, wantFor } if haveCredentialName != wantCredentialName { - return fmt.Errorf("unexpected repo credential name; want: %s, have %s", wantCredentialName, haveCredentialName) + return fmt.Errorf("unexpected repository credential name; want: %s, have %s", wantCredentialName, haveCredentialName) } haveFormat := tr.GetFormat() if haveFormat != wantFormat { - return fmt.Errorf("unexpected repo format; want: %s, have %s", wantFormat, haveFormat) + return fmt.Errorf("unexpected repository format; want: %s, have %s", wantFormat, haveFormat) } haveType := tr.GetType() if haveType != wantType { - return fmt.Errorf("unexpected repo type; want: %s, have %s", wantType, haveType) + return fmt.Errorf("unexpected repository type; want: %s, have %s", wantType, haveType) } return nil diff --git a/pkg/repo/repoprovider.go b/pkg/repo/repoprovider.go index 0473f0367..b46d9acc4 100644 --- a/pkg/repo/repoprovider.go +++ b/pkg/repo/repoprovider.go @@ -29,28 +29,28 @@ import ( "sync" ) -// RepoProvider is a factory for ChartRepo instances. +// RepoProvider is a factory for IChartRepo instances. type RepoProvider interface { - GetRepoByURL(URL string) (ChartRepo, error) - GetRepoByName(repoName string) (ChartRepo, error) + GetRepoByURL(URL string) (IChartRepo, error) + GetRepoByName(repoName string) (IChartRepo, error) GetChartByReference(reference string) (*chart.Chart, error) } type repoProvider struct { sync.RWMutex - rs Service - cp CredentialProvider + rs IRepoService + cp ICredentialProvider gcsrp GCSRepoProvider - repos map[string]ChartRepo + repos map[string]IChartRepo } // NewRepoProvider creates a new repository provider. -func NewRepoProvider(rs Service, gcsrp GCSRepoProvider, cp CredentialProvider) RepoProvider { +func NewRepoProvider(rs IRepoService, gcsrp GCSRepoProvider, cp ICredentialProvider) RepoProvider { return newRepoProvider(rs, gcsrp, cp) } // newRepoProvider creates a new repository provider. -func newRepoProvider(rs Service, gcsrp GCSRepoProvider, cp CredentialProvider) *repoProvider { +func newRepoProvider(rs IRepoService, gcsrp GCSRepoProvider, cp ICredentialProvider) *repoProvider { if rs == nil { rs = NewInmemRepoService() } @@ -63,18 +63,18 @@ func newRepoProvider(rs Service, gcsrp GCSRepoProvider, cp CredentialProvider) * gcsrp = NewGCSRepoProvider(cp) } - repos := make(map[string]ChartRepo) + repos := make(map[string]IChartRepo) rp := &repoProvider{rs: rs, gcsrp: gcsrp, cp: cp, repos: repos} return rp } // GetRepoService returns the repository service used by this repository provider. -func (rp *repoProvider) GetRepoService() Service { +func (rp *repoProvider) GetRepoService() IRepoService { return rp.rs } // GetCredentialProvider returns the credential provider used by this repository provider. -func (rp *repoProvider) GetCredentialProvider() CredentialProvider { +func (rp *repoProvider) GetCredentialProvider() ICredentialProvider { return rp.cp } @@ -84,7 +84,7 @@ func (rp *repoProvider) GetGCSRepoProvider() GCSRepoProvider { } // GetRepoByName returns the repository with the given name. -func (rp *repoProvider) GetRepoByName(repoName string) (ChartRepo, error) { +func (rp *repoProvider) GetRepoByName(repoName string) (IChartRepo, error) { rp.Lock() defer rp.Unlock() @@ -100,7 +100,7 @@ func (rp *repoProvider) GetRepoByName(repoName string) (ChartRepo, error) { return rp.createRepoByType(cr) } -func (rp *repoProvider) createRepoByType(r Repo) (ChartRepo, error) { +func (rp *repoProvider) createRepoByType(r IRepo) (IChartRepo, error) { switch r.GetType() { case GCSRepoType: cr, err := rp.gcsrp.GetGCSRepo(r) @@ -114,7 +114,7 @@ func (rp *repoProvider) createRepoByType(r Repo) (ChartRepo, error) { return nil, fmt.Errorf("unknown repository type: %s", r.GetType()) } -func (rp *repoProvider) createRepo(cr ChartRepo) (ChartRepo, error) { +func (rp *repoProvider) createRepo(cr IChartRepo) (IChartRepo, error) { name := cr.GetName() if _, ok := rp.repos[name]; ok { return nil, fmt.Errorf("respository named %s already exists", name) @@ -125,7 +125,7 @@ func (rp *repoProvider) createRepo(cr ChartRepo) (ChartRepo, error) { } // GetRepoByURL returns the repository whose URL is a prefix of the given URL. -func (rp *repoProvider) GetRepoByURL(URL string) (ChartRepo, error) { +func (rp *repoProvider) GetRepoByURL(URL string) (IChartRepo, error) { rp.Lock() defer rp.Unlock() @@ -141,8 +141,8 @@ func (rp *repoProvider) GetRepoByURL(URL string) (ChartRepo, error) { return rp.createRepoByType(cr) } -func (rp *repoProvider) findRepoByURL(URL string) ChartRepo { - var found ChartRepo +func (rp *repoProvider) findRepoByURL(URL string) IChartRepo { + var found IChartRepo for _, r := range rp.repos { rURL := r.GetURL() if strings.HasPrefix(URL, rURL) { @@ -178,17 +178,17 @@ func (rp *repoProvider) GetChartByReference(reference string) (*chart.Chart, err return r.GetChart(name) } -// GCSRepoProvider is a factory for GCS Repo instances. +// GCSRepoProvider is a factory for GCS IRepo instances. type GCSRepoProvider interface { - GetGCSRepo(r Repo) (ObjectStorageRepo, error) + GetGCSRepo(r IRepo) (IStorageRepo, error) } type gcsRepoProvider struct { - cp CredentialProvider + cp ICredentialProvider } // NewGCSRepoProvider creates a GCSRepoProvider. -func NewGCSRepoProvider(cp CredentialProvider) GCSRepoProvider { +func NewGCSRepoProvider(cp ICredentialProvider) GCSRepoProvider { if cp == nil { cp = NewInmemCredentialProvider() } @@ -198,7 +198,7 @@ func NewGCSRepoProvider(cp CredentialProvider) GCSRepoProvider { // GetGCSRepo returns a new Google Cloud Storage repository. If a credential is specified, it will try to // fetch it and use it, and if the credential isn't found, it will fall back to an unauthenticated client. -func (gcsrp gcsRepoProvider) GetGCSRepo(r Repo) (ObjectStorageRepo, error) { +func (gcsrp gcsRepoProvider) GetGCSRepo(r IRepo) (IStorageRepo, error) { client, err := gcsrp.createGCSClient(r.GetCredentialName()) if err != nil { return nil, err diff --git a/pkg/repo/repoprovider_test.go b/pkg/repo/repoprovider_test.go index d0891266e..be1db8317 100644 --- a/pkg/repo/repoprovider_test.go +++ b/pkg/repo/repoprovider_test.go @@ -50,9 +50,9 @@ func TestRepoProvider(t *testing.T) { t.Fatal(err) } - castRepo, ok := haveRepo.(ObjectStorageRepo) + castRepo, ok := haveRepo.(IStorageRepo) if !ok { - t.Fatalf("invalid repo type, want: ObjectStorageRepo, have: %T.", haveRepo) + t.Fatalf("invalid repo type, want: IStorageRepo, have: %T.", haveRepo) } wantBucket := GCSPublicRepoBucket diff --git a/pkg/repo/secrets_credential_provider.go b/pkg/repo/secrets_credential_provider.go index 2e6e73676..3747e4a48 100644 --- a/pkg/repo/secrets_credential_provider.go +++ b/pkg/repo/secrets_credential_provider.go @@ -53,7 +53,7 @@ type SecretsCredentialProvider struct { } // NewSecretsCredentialProvider creates a new secrets credential provider. -func NewSecretsCredentialProvider() CredentialProvider { +func NewSecretsCredentialProvider() ICredentialProvider { kubernetesConfig := &util.KubernetesConfig{ KubePath: *kubePath, KubeService: *kubeService, diff --git a/pkg/repo/types.go b/pkg/repo/types.go index 4f580142e..e507f9bbb 100644 --- a/pkg/repo/types.go +++ b/pkg/repo/types.go @@ -44,8 +44,8 @@ type RepoCredential struct { ServiceAccount JWTTokenCredential `json:"serviceaccount,omitempty"` } -// CredentialProvider provides credentials for chart repositories. -type CredentialProvider interface { +// ICredentialProvider provides credentials for chart repositories. +type ICredentialProvider interface { // SetCredential sets the credential for a repository. // May not be supported by some repository services. SetCredential(name string, credential *RepoCredential) error @@ -68,8 +68,17 @@ const ( FlatRepoFormat = RepoFormat("flat") ) -// Repo abstracts a repository. -type Repo interface { +// Repo describes a repository +type Repo struct { + Name string `json:"name"` // Friendly name for this repository + URL string `json:"url"` // URL to the root of this repository + CredentialName string `json:"credentialname"` // Credential name used to access this repository + Format RepoFormat `json:"format"` // Format of this repository + Type RepoType `json:"type"` // Technology implementing this repository +} + +// IRepo abstracts a repository. +type IRepo interface { // GetName returns the friendly name of this repository. GetName() string // GetURL returns the URL to the root of this repository. @@ -82,10 +91,10 @@ type Repo interface { GetType() RepoType } -// ChartRepo abstracts a place that holds charts. -type ChartRepo interface { - // A ChartRepo is a Repo - Repo +// IChartRepo abstracts a place that holds charts. +type IChartRepo interface { + // A IChartRepo is a IRepo + IRepo // ListCharts lists charts in this repository whose string values // conform to the supplied regular expression, or all charts if regex is nil @@ -95,27 +104,27 @@ type ChartRepo interface { GetChart(name string) (*chart.Chart, error) } -// ObjectStorageRepo abstracts a repository that resides in Object Storage, +// IStorageRepo abstracts a repository that resides in Object Storage, // such as Google Cloud Storage, AWS S3, etc. -type ObjectStorageRepo interface { - // An ObjectStorageRepo is a ChartRepo - ChartRepo +type IStorageRepo interface { + // An IStorageRepo is a IChartRepo + IChartRepo // GetBucket returns the name of the bucket that contains this repository. GetBucket() string } -// Service maintains a list of chart repositories that defines the scope of all +// IRepoService maintains a list of chart repositories that defines the scope of all // repository based operations, such as search and chart reference resolution. -type Service interface { +type IRepoService interface { // List returns the list of all known chart repositories - List() ([]Repo, error) + List() ([]IRepo, error) // Create adds a known repository to the list - Create(repository Repo) error + Create(repository IRepo) error // Get returns the repository with the given name - Get(name string) (Repo, error) + Get(name string) (IRepo, error) // GetByURL returns the repository that backs the given URL - GetByURL(URL string) (Repo, error) + GetByURL(URL string) (IRepo, error) // Delete removes a known repository from the list Delete(name string) error }