diff --git a/internal/index/indexscanner/scanner.go b/internal/index/indexscanner/scanner.go index 58684e46..7d1e4aa4 100644 --- a/internal/index/indexscanner/scanner.go +++ b/internal/index/indexscanner/scanner.go @@ -108,6 +108,9 @@ func ReadPlugin(f io.ReadCloser) (index.Plugin, error) { func ReadReceiptFromFile(path string) (index.Receipt, error) { var receipt index.Receipt err := readFromFile(path, &receipt) + if receipt.Status.Source.Name == "" { + receipt.Status.Source.Name = constants.DefaultIndexName + } return receipt, err } diff --git a/internal/index/indexscanner/scanner_test.go b/internal/index/indexscanner/scanner_test.go index de6da1a2..5162a2e6 100644 --- a/internal/index/indexscanner/scanner_test.go +++ b/internal/index/indexscanner/scanner_test.go @@ -19,8 +19,13 @@ import ( "path/filepath" "testing" + "github.com/google/go-cmp/cmp" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + + "sigs.k8s.io/krew/internal/testutil" + "sigs.k8s.io/krew/pkg/constants" + "sigs.k8s.io/krew/pkg/index" ) func TestReadPluginFile(t *testing.T) { @@ -90,6 +95,62 @@ func TestReadPluginFile(t *testing.T) { } } +func TestReadReceiptFromFile(t *testing.T) { + type args struct { + status index.ReceiptStatus + } + tests := []struct { + name string + args args + wantStatus index.ReceiptStatus + }{ + { + name: "read receipt of plugin from index foo", + args: args{ + status: index.ReceiptStatus{ + Source: index.SourceIndex{ + Name: "foo", + }, + }, + }, + wantStatus: index.ReceiptStatus{ + Source: index.SourceIndex{ + Name: "foo", + }, + }, + }, + { + name: "read receipt of plugin without status", + args: args{ + status: index.ReceiptStatus{}, + }, + wantStatus: index.ReceiptStatus{ + Source: index.SourceIndex{ + Name: constants.DefaultIndexName, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tmpDir, cleanup := testutil.NewTempDir(t) + defer cleanup() + + plugin := "plugin" + constants.ManifestExtension + testReceipt := testutil.NewReceipt().WithPlugin(testutil.NewPlugin().V()).WithStatus(tt.args.status).V() + tmpDir.WriteYAML(plugin, testReceipt) + + gotReceipt, err := ReadReceiptFromFile(tmpDir.Path(plugin)) + if err != nil { + t.Fatalf("ReadReceiptFromFile() error: %v", err) + } + if diff := cmp.Diff(tt.wantStatus, gotReceipt.Status); diff != "" { + t.Errorf("expected matching receipts: %s\n", diff) + } + }) + } +} + func TestReadPluginFile_preservesNotFoundErr(t *testing.T) { _, err := ReadPluginFromFile(filepath.Join(testdataPath(t), "does-not-exist.yaml")) if err == nil { diff --git a/internal/installation/receipt/receipt_test.go b/internal/installation/receipt/receipt_test.go index 658ebf1b..01f98da5 100644 --- a/internal/installation/receipt/receipt_test.go +++ b/internal/installation/receipt/receipt_test.go @@ -22,7 +22,6 @@ import ( "sigs.k8s.io/krew/internal/index/indexscanner" "sigs.k8s.io/krew/internal/testutil" - "sigs.k8s.io/krew/pkg/index" ) func TestStore(t *testing.T) { @@ -30,18 +29,19 @@ func TestStore(t *testing.T) { defer cleanup() testPlugin := testutil.NewPlugin().WithName("some-plugin").WithPlatforms(testutil.NewPlatform().V()).V() + testReceipt := testutil.NewReceipt().WithPlugin(testPlugin).V() dest := tmpDir.Path("some-plugin.yaml") if err := Store(testPlugin, dest); err != nil { t.Fatal(err) } - actual, err := indexscanner.LoadPluginByName(tmpDir.Root(), "some-plugin") + actual, err := indexscanner.ReadReceiptFromFile(dest) if err != nil { t.Fatal(err) } - if diff := cmp.Diff(&testPlugin, &actual); diff != "" { + if diff := cmp.Diff(&testReceipt, &actual); diff != "" { t.Fatal(diff) } } @@ -59,7 +59,7 @@ func TestLoad(t *testing.T) { if err != nil { t.Fatal(err) } - testPluginReceipt := index.Receipt{Plugin: testPlugin} + testPluginReceipt := testutil.NewReceipt().WithPlugin(testPlugin).V() if diff := cmp.Diff(&gotPlugin, &testPluginReceipt); diff != "" { t.Fatal(diff) } diff --git a/internal/testutil/receipt.go b/internal/testutil/receipt.go new file mode 100644 index 00000000..175b8b3d --- /dev/null +++ b/internal/testutil/receipt.go @@ -0,0 +1,37 @@ +// Copyright 2019 The Kubernetes Authors. +// +// 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 testutil + +import ( + "sigs.k8s.io/krew/pkg/constants" + "sigs.k8s.io/krew/pkg/index" +) + +type Receipt struct{ v index.Receipt } + +// NewReceipt builds an index.Receipt that is valid. +func NewReceipt() *Receipt { + return &Receipt{v: index.Receipt{ + Status: index.ReceiptStatus{ + Source: index.SourceIndex{ + Name: constants.DefaultIndexName, + }, + }, + }} +} + +func (r *Receipt) WithPlugin(p index.Plugin) *Receipt { r.v.Plugin = p; return r } +func (r *Receipt) WithStatus(s index.ReceiptStatus) *Receipt { r.v.Status = s; return r } +func (r *Receipt) V() index.Receipt { return r.v } diff --git a/pkg/index/types.go b/pkg/index/types.go index 791d946a..e2b19325 100644 --- a/pkg/index/types.go +++ b/pkg/index/types.go @@ -62,4 +62,17 @@ type FileOperation struct { // Receipt describes a plugin receipt file. type Receipt struct { Plugin `json:",inline" yaml:",inline"` + + Status ReceiptStatus `json:"status"` +} + +// ReceiptStatus contains information about the installed plugin. +type ReceiptStatus struct { + Source SourceIndex `json:"source"` +} + +// SourceIndex contains information about the index a plugin was installed from. +type SourceIndex struct { + // Name is the configured name of an index a plugin was installed from. + Name string `json:"name"` }