Repository: kubernetes-sigs/krew
Pull request #694 (2021-02-26 21:13:20)

hack: use go1.16 'go install pkg@ver' mode
cleaning up our hack/ scripts a bit.

k8s-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/krew/pull/694#" title="Author self-approved">ahmetb</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fkrew).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubernetes-sigs/krew/blob/master/OWNERS)~~ [ahmetb]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
corneliusweig: /lgtm
/hold
Nice code reduction!
ahmetb: should be good to review now.
k8s-ci-robot: New changes are detected. LGTM label has been removed.

Patch:
diff --git a/hack/.gitignore b/hack/.gitignore
deleted file mode 100644
index 4724abf..0000000
--- a/hack/.gitignore
+++ /dev/null
@@ -1,1 +0,0 @@
-/release-notes
diff --git a/hack/install-gox.sh b/hack/install-gox.sh
index a644bba..471baf2 100755
--- a/hack/install-gox.sh
+++ b/hack/install-gox.sh
@@ -17,24 +17,12 @@
 set -euo pipefail
 [[ -n "${DEBUG:-}" ]] && set -x
 
-scratch_dir="$(mktemp -d)"
-cleanup() {
-  rm -rf "${scratch_dir}"
-}
-trap cleanup EXIT
-
-install_gox() {
-  cd "${scratch_dir}"
-  go mod init foo
-  go get github.com/mitchellh/gox@v1.0.1
-  cd -
-}
-
 ensure_gox() {
   command -v "gox" &>/dev/null
 }
 
-install_gox
+go install github.com/mitchellh/gox@v1.0.1
+
 if ! ensure_gox; then
   echo >&2 "gox not in PATH"
   exit 1
diff --git a/hack/make-release-notes.sh b/hack/make-release-notes.sh
index 39b1518..7e55cbd 100755
--- a/hack/make-release-notes.sh
+++ b/hack/make-release-notes.sh
@@ -20,7 +20,7 @@
 
 set -euo pipefail
 
-SCRIPTDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+gopath="$(go env GOPATH)"
 
 TAG="${TAG:?TAG environment variable must be set for this script}"
 if ! [[ "$TAG" =~ v.* ]]; then
@@ -38,20 +38,10 @@ download_assets=(
   krew.yaml
 )
 
-install_release_notes() {
-  relnotes_dir="$(mktemp -d)"
-  trap 'rm -rf -- ${relnotes_dir}' EXIT
-
-  cd "$relnotes_dir"
-  go mod init foo
-  GOBIN="${SCRIPTDIR}" go get github.com/corneliusweig/release-notes@v0.1.0
-  cd -
-}
-
-# install release-notes if not present in the hack folder
-if ! [[ -x "${SCRIPTDIR}/release-notes" ]]; then
-  echo >&2 'Installing release-notes'
-  install_release_notes
+# install release-notes tool if not present
+if [[ ! -f "${gopath}/bin/release-notes" ]]; then
+  echo >&2 'Installing release-notes tool...'
+  go install github.com/corneliusweig/release-notes@v0.1.0
 fi
 
 echo "Installation"
@@ -79,6 +69,7 @@ echo '<details>'
 echo '<summary>Merged pull requests</summary>'
 echo # this empty line is important for correct markdown rendering
 # you can pass your github token with --token here if you run out of requests
-"${SCRIPTDIR}/release-notes" kubernetes-sigs krew
+
+"${gopath}/bin/release-notes" kubernetes-sigs krew
 echo '</details>'
 echo
diff --git a/hack/run-lint.sh b/hack/run-lint.sh
index b23c3f2..79373ce 100755
--- a/hack/run-lint.sh
+++ b/hack/run-lint.sh
@@ -29,38 +29,17 @@ fi
 # configured by .golangci.yml
 "$gopath/bin/golangci-lint" run
 
-install_impi() {
-  impi_dir="$(mktemp -d)"
-  trap 'rm -rf -- ${impi_dir}' EXIT
-
-  cd "${impi_dir}"
-  go mod init foo
-  go get github.com/pavius/impi/cmd/impi@c1cbdcb
-  cd -
-}
-
-# install impi that ensures import grouping is done consistently
 if ! [[ -x "${gopath}/bin/impi" ]]; then
   echo >&2 'Installing impi'
-  install_impi
+  go install github.com/pavius/impi/cmd/impi@c1cbdcb
 fi
 
 "$gopath/bin/impi" --local sigs.k8s.io/krew --scheme stdThirdPartyLocal ./...
 
-install_shfmt() {
-  shfmt_dir="$(mktemp -d)"
-  trap 'rm -rf -- ${shfmt_dir}' EXIT
-
-  cd "${shfmt_dir}"
-  go mod init foo
-  go get mvdan.cc/sh/v3/cmd/shfmt@v3.0.0
-  cd -
-}
-
 # install shfmt that ensures consistent format in shell scripts
 if ! [[ -x "${gopath}/bin/shfmt" ]]; then
   echo >&2 'Installing shfmt'
-  install_shfmt
+  go install mvdan.cc/sh/v3/cmd/shfmt@v3.0.0
 fi
 
 SCRIPTDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
diff --git a/internal/installation/install.go b/internal/installation/install.go
index 24615da..71fbdaf 100644
--- a/internal/installation/install.go
+++ b/internal/installation/install.go
@@ -22,6 +22,7 @@ import (
 	"strings"
 
 	"github.com/pkg/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/klog"
 
 	"sigs.k8s.io/krew/internal/download"
@@ -84,8 +85,9 @@ func Install(p environment.Paths, plugin index.Plugin, indexName string, opts In
 	}, opts); err != nil {
 		return errors.Wrap(err, "install failed")
 	}
+
 	klog.V(3).Infof("Storing install receipt for plugin %s", plugin.Name)
-	err = receipt.Store(receipt.New(plugin, indexName), p.PluginInstallReceiptPath(plugin.Name))
+	err = receipt.Store(receipt.New(plugin, indexName, metav1.Now()), p.PluginInstallReceiptPath(plugin.Name))
 	return errors.Wrap(err, "installation receipt could not be stored, uninstall may fail")
 }
 
diff --git a/internal/installation/receipt/receipt.go b/internal/installation/receipt/receipt.go
index 83a2735..3c1a0e7 100644
--- a/internal/installation/receipt/receipt.go
+++ b/internal/installation/receipt/receipt.go
@@ -18,6 +18,7 @@ import (
 	"io/ioutil"
 
 	"github.com/pkg/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"sigs.k8s.io/yaml"
 
 	"sigs.k8s.io/krew/internal/index/indexscanner"
@@ -43,7 +44,8 @@ func Load(path string) (index.Receipt, error) {
 }
 
 // New returns a new receipt with the given plugin and index name.
-func New(plugin index.Plugin, indexName string) index.Receipt {
+func New(plugin index.Plugin, indexName string, timestamp metav1.Time) index.Receipt {
+	plugin.CreationTimestamp = timestamp
 	return index.Receipt{
 		Plugin: plugin,
 		Status: index.ReceiptStatus{
diff --git a/internal/installation/upgrade.go b/internal/installation/upgrade.go
index bac6d32..711e977 100644
--- a/internal/installation/upgrade.go
+++ b/internal/installation/upgrade.go
@@ -78,7 +78,7 @@ func Upgrade(p environment.Paths, plugin index.Plugin, indexName string) error {
 	}
 
 	klog.V(2).Infof("Upgrading install receipt for plugin %s", plugin.Name)
-	if err = receipt.Store(receipt.New(plugin, indexName), p.PluginInstallReceiptPath(plugin.Name)); err != nil {
+	if err = receipt.Store(receipt.New(plugin, indexName, installReceipt.CreationTimestamp), p.PluginInstallReceiptPath(plugin.Name)); err != nil {
 		return errors.Wrap(err, "installation receipt could not be stored, uninstall may fail")
 	}
 


Test patch:
diff --git a/integration_test/install_test.go b/integration_test/install_test.go
index 8004603..a5d6c03 100644
--- a/integration_test/install_test.go
+++ b/integration_test/install_test.go
@@ -21,6 +21,7 @@ import (
 	"strings"
 	"testing"
 
+	"sigs.k8s.io/krew/internal/environment"
 	"sigs.k8s.io/krew/pkg/constants"
 )
 
@@ -44,6 +45,11 @@ func TestKrewInstall(t *testing.T) {
 	test.Krew("install", validPlugin).RunOrFailOutput()
 	test.AssertExecutableInPATH("kubectl-" + validPlugin)
 	test.AssertPluginFromIndex(validPlugin, "default")
+
+	receiptPath := environment.NewPaths(test.Root()).PluginInstallReceiptPath(validPlugin)
+	if r := test.loadReceipt(receiptPath); r.CreationTimestamp.Time.IsZero() {
+		t.Fatal("expected receipt to have a valid creationTimestamp")
+	}
 }
 
 func TestKrewInstallReRun(t *testing.T) {
diff --git a/integration_test/testutil_test.go b/integration_test/testutil_test.go
index 102e351..9bd1100 100644
--- a/integration_test/testutil_test.go
+++ b/integration_test/testutil_test.go
@@ -34,6 +34,7 @@ import (
 	"sigs.k8s.io/krew/internal/installation/receipt"
 	"sigs.k8s.io/krew/internal/testutil"
 	"sigs.k8s.io/krew/pkg/constants"
+	"sigs.k8s.io/krew/pkg/index"
 )
 
 const (
@@ -161,10 +162,7 @@ func (it *ITest) AssertPluginFromIndex(plugin, indexName string) {
 	it.t.Helper()
 
 	receiptPath := environment.NewPaths(it.Root()).PluginInstallReceiptPath(plugin)
-	r, err := receipt.Load(receiptPath)
-	if err != nil {
-		it.t.Fatalf("error loading receipt: %v", err)
-	}
+	r := it.loadReceipt(receiptPath)
 	if r.Status.Source.Name != indexName {
 		it.t.Errorf("wanted index '%s', got: '%s'", indexName, r.Status.Source.Name)
 	}
@@ -268,6 +266,14 @@ func (it *ITest) TempDir() *testutil.TempDir {
 	return it.tempDir
 }
 
+func (it *ITest) loadReceipt(path string) index.Receipt {
+	pluginReceipt, err := receipt.Load(path)
+	if err != nil {
+		it.t.Fatalf("error loading receipt: %v", err)
+	}
+	return pluginReceipt
+}
+
 // InitializeIndex initializes the krew index in `$root/index` with the actual krew-index.
 // It caches the index tree as in-memory tar after the first run.
 func (it *ITest) initializeIndex() {
diff --git a/integration_test/upgrade_test.go b/integration_test/upgrade_test.go
index b9cbffe..c427466 100644
--- a/integration_test/upgrade_test.go
+++ b/integration_test/upgrade_test.go
@@ -45,8 +45,9 @@ func TestKrewUpgrade(t *testing.T) {
 
 	// plugins installed via manifest get the special "detached" index so this needs to
 	// be changed to default in order for it to be upgraded here
-	receipt := environment.NewPaths(test.Root()).PluginInstallReceiptPath(validPlugin)
-	modifyReceiptIndex(t, receipt, "default")
+	receiptPath := environment.NewPaths(test.Root()).PluginInstallReceiptPath(validPlugin)
+	modifyReceiptIndex(t, receiptPath, "default")
+	initialCreationTimestamp := test.loadReceipt(receiptPath).CreationTimestamp
 
 	initialLocation := resolvePluginSymlink(test, validPlugin)
 	test.Krew("upgrade").RunOrFail()
@@ -54,6 +55,11 @@ func TestKrewUpgrade(t *testing.T) {
 	if initialLocation == eventualLocation {
 		t.Errorf("Expecting the plugin path to change but was the same.")
 	}
+
+	eventualCreationTimestamp := test.loadReceipt(receiptPath).CreationTimestamp
+	if initialCreationTimestamp != eventualCreationTimestamp {
+		t.Errorf("expected the receipt creationTimestamp to remain unchanged after upgrade")
+	}
 }
 
 func TestKrewUpgradePluginsFromCustomIndex(t *testing.T) {
@@ -64,14 +70,14 @@ func TestKrewUpgradePluginsFromCustomIndex(t *testing.T) {
 	test.WithDefaultIndex().WithCustomIndexFromDefault("foo")
 	test.Krew("install", "foo/"+validPlugin).RunOrFail()
 
-	receipt := environment.NewPaths(test.Root()).PluginInstallReceiptPath(validPlugin)
-	modifyManifestVersion(t, receipt, "v0.0.0")
+	receiptPath := environment.NewPaths(test.Root()).PluginInstallReceiptPath(validPlugin)
+	modifyManifestVersion(t, receiptPath, "v0.0.0")
 	out := string(test.Krew("upgrade").RunOrFailOutput())
 	if !strings.Contains(out, "Upgrading plugin: foo/"+validPlugin) {
 		t.Errorf("expected plugin foo/%s to be upgraded", validPlugin)
 	}
 
-	modifyManifestVersion(t, receipt, "v0.0.0")
+	modifyManifestVersion(t, receiptPath, "v0.0.0")
 	out = string(test.Krew("upgrade", validPlugin).RunOrFailOutput())
 	if !strings.Contains(out, "Upgrading plugin: foo/"+validPlugin) {
 		t.Errorf("expected plugin foo/%s to be upgraded", validPlugin)
@@ -101,8 +107,8 @@ func TestKrewUpgradeNoSecurityWarningForCustomIndex(t *testing.T) {
 	test.WithDefaultIndex().WithCustomIndexFromDefault("foo")
 	test.Krew("install", "foo/"+validPlugin).RunOrFail()
 
-	receipt := environment.NewPaths(test.Root()).PluginInstallReceiptPath(validPlugin)
-	modifyManifestVersion(t, receipt, "v0.0.1")
+	pluginReceipt := environment.NewPaths(test.Root()).PluginInstallReceiptPath(validPlugin)
+	modifyManifestVersion(t, pluginReceipt, "v0.0.1")
 	out := string(test.Krew("upgrade").RunOrFailOutput())
 	if strings.Contains(out, "Run them at your own risk") {
 		t.Errorf("expected install of custom plugin to not show security warning: %v", out)
diff --git a/internal/installation/receipt/receipt_test.go b/internal/installation/receipt/receipt_test.go
index ecb7e8e..4f0ac08 100644
--- a/internal/installation/receipt/receipt_test.go
+++ b/internal/installation/receipt/receipt_test.go
@@ -19,6 +19,7 @@ import (
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	"sigs.k8s.io/krew/internal/index/indexscanner"
 	"sigs.k8s.io/krew/internal/testutil"
@@ -72,10 +73,12 @@ func TestLoad_preservesNonExistsError(t *testing.T) {
 }
 
 func TestNew(t *testing.T) {
+	timestamp := metav1.Now()
 	testPlugin := testutil.NewPlugin().WithName("foo").WithPlatforms(testutil.NewPlatform().V()).V()
 	wantReceipt := testutil.NewReceipt().WithPlugin(testPlugin).V()
+	wantReceipt.CreationTimestamp = timestamp
 
-	gotReceipt := New(testPlugin, constants.DefaultIndexName)
+	gotReceipt := New(testPlugin, constants.DefaultIndexName, timestamp)
 	if diff := cmp.Diff(gotReceipt, wantReceipt); diff != "" {
 		t.Fatalf("expected receipts to match: %s", diff)
 	}