diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index d726ecd8a0..dbdefdd8ae 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -12,6 +12,21 @@ | https://github.com/knative/client/pull/[#] //// +## v0.15.2 (2020-06-16) + +[cols="1,10,3", options="header", width="100%"] +|=== +| | Description | PR + +| 🐛 +| Return error message when using --untag with nonexistent tag +| https://github.com/knative/client/pull/880[#880] + +| ✨ +| Update go.mod to specify the module is go1.14 +| https://github.com/knative/client/pull/866[#866] +|=== + ## v0.15.1 (2020-06-03) [cols="1,10,3", options="header", width="100%"] diff --git a/go.mod b/go.mod index c5dbddce57..d31736c027 100644 --- a/go.mod +++ b/go.mod @@ -32,4 +32,4 @@ replace ( k8s.io/code-generator => k8s.io/code-generator v0.16.4 ) -go 1.13 +go 1.14 diff --git a/hack/build.sh b/hack/build.sh index 214d2aa54e..7dc3e43d0c 100755 --- a/hack/build.sh +++ b/hack/build.sh @@ -16,6 +16,9 @@ set -o pipefail +[[ ! -v REPO_ROOT_DIR ]] && REPO_ROOT_DIR="$(git rev-parse --show-toplevel)" +readonly REPO_ROOT_DIR + source_dirs="cmd pkg test lib" # Store for later @@ -110,21 +113,38 @@ go_fmt() { find $(echo $source_dirs) -name "*.go" -print0 | xargs -0 gofmt -s -w } +# Run a go tool, installing it first if necessary. +# Parameters: $1 - tool package/dir for go get/install. +# $2 - tool to run. +# $3..$n - parameters passed to the tool. +run_go_tool() { + local tool=$2 + local install_failed=0 + if [[ -z "$(which ${tool})" ]]; then + local action=get + [[ $1 =~ ^[\./].* ]] && action=install + # Avoid running `go get` from root dir of the repository, as it can change go.sum and go.mod files. + # See discussions in https://github.com/golang/go/issues/27643. + if [[ ${action} == "get" && $(pwd) == "${REPO_ROOT_DIR}" ]]; then + local temp_dir="$(mktemp -d)" + # Swallow the output as we are returning the stdout in the end. + pushd "${temp_dir}" > /dev/null 2>&1 + GOFLAGS="" go ${action} "$1" || install_failed=1 + popd > /dev/null 2>&1 + else + GOFLAGS="" go ${action} "$1" || install_failed=1 + fi + fi + (( install_failed )) && return ${install_failed} + shift 2 + ${tool} "$@" +} + + source_format() { set +e - which goimports >/dev/null 2>&1 - if [ $? -ne 0 ]; then - echo "✋ No 'goimports' found. Please use" - echo "✋ go install golang.org/x/tools/cmd/goimports" - echo "✋ to enable import cleanup. Import cleanup skipped." - - # Run go fmt instead - go_fmt - else - echo "🧽 ${X}Format" - goimports -w $(echo $source_dirs) - find $(echo $source_dirs) -name "*.go" -print0 | xargs -0 gofmt -s -w - fi + run_go_tool golang.org/x/tools/cmd/goimports goimports -w $(echo $source_dirs) + find $(echo $source_dirs) -name "*.go" -print0 | xargs -0 gofmt -s -w set -e } diff --git a/hack/verify-codegen.sh b/hack/verify-codegen.sh index ee9036a308..511cabc01e 100755 --- a/hack/verify-codegen.sh +++ b/hack/verify-codegen.sh @@ -20,9 +20,6 @@ set -o pipefail source $(dirname $0)/../scripts/test-infra/library.sh -# Needed later -go install golang.org/x/tools/cmd/goimports - "${REPO_ROOT_DIR}"/hack/build.sh --codegen if output="$(git status --porcelain)" && [ -z "$output" ]; then echo "${REPO_ROOT_DIR} is up to date." diff --git a/lib/test/service.go b/lib/test/service.go index 508e106e83..69f8613b68 100644 --- a/lib/test/service.go +++ b/lib/test/service.go @@ -72,6 +72,15 @@ func ServiceUpdate(r *KnRunResultCollector, serviceName string, args ...string) assert.Check(r.T(), util.ContainsAllIgnoreCase(out.Stdout, "updating", "service", serviceName, "ready")) } +// ServiceUpdateWithError verifies service update operation with given arguments in sync mode +// when expecting an error +func ServiceUpdateWithError(r *KnRunResultCollector, serviceName string, args ...string) { + fullArgs := append([]string{}, "service", "update", serviceName) + fullArgs = append(fullArgs, args...) + out := r.KnTest().Kn().Run(fullArgs...) + r.AssertError(out) +} + // ServiceDelete verifies service deletion in sync mode func ServiceDelete(r *KnRunResultCollector, serviceName string) { out := r.KnTest().Kn().Run("service", "delete", "--wait", serviceName) diff --git a/pkg/kn/commands/service/update.go b/pkg/kn/commands/service/update.go index 3499472b3a..c8b64410f8 100644 --- a/pkg/kn/commands/service/update.go +++ b/pkg/kn/commands/service/update.go @@ -92,7 +92,7 @@ func NewServiceUpdateCommand(p *commands.KnParams) *cobra.Command { } if trafficFlags.Changed(cmd) { - traffic, err := traffic.Compute(cmd, service.Spec.Traffic, &trafficFlags) + traffic, err := traffic.Compute(cmd, service.Spec.Traffic, &trafficFlags, service.Name) if err != nil { return nil, err } diff --git a/pkg/kn/commands/service/update_test.go b/pkg/kn/commands/service/update_test.go index 0549bbf897..6b7ee0271c 100644 --- a/pkg/kn/commands/service/update_test.go +++ b/pkg/kn/commands/service/update_test.go @@ -737,6 +737,15 @@ func TestServiceUpdateDeletionTimestampNotNil(t *testing.T) { assert.ErrorContains(t, err, "service") } +func TestServiceUpdateTagDoesNotExist(t *testing.T) { + orig := newEmptyService() + + _, _, _, err := fakeServiceUpdate(orig, []string{ + "service", "update", "foo", "--untag", "foo", "--no-wait"}) + + assert.Assert(t, util.ContainsAll(err.Error(), "tag(s)", "foo", "not present", "service", "foo")) +} + func newEmptyService() *servingv1.Service { ret := &servingv1.Service{ TypeMeta: metav1.TypeMeta{ diff --git a/pkg/kn/traffic/compute.go b/pkg/kn/traffic/compute.go index ab0d6bb654..ef027bc22a 100644 --- a/pkg/kn/traffic/compute.go +++ b/pkg/kn/traffic/compute.go @@ -83,13 +83,15 @@ func (e ServiceTraffic) isTagPresent(tag string) bool { return false } -func (e ServiceTraffic) untagRevision(tag string) { +func (e ServiceTraffic) untagRevision(tag string, serviceName string) bool { for i, target := range e { if target.Tag == tag { e[i].Tag = "" - break + return true } } + + return false } func (e ServiceTraffic) isRevisionPresent(revision string) bool { @@ -267,7 +269,8 @@ func verifyInputSanity(trafficFlags *flags.Traffic) error { } // Compute takes service traffic targets and updates per given traffic flags -func Compute(cmd *cobra.Command, targets []servingv1.TrafficTarget, trafficFlags *flags.Traffic) ([]servingv1.TrafficTarget, error) { +func Compute(cmd *cobra.Command, targets []servingv1.TrafficTarget, + trafficFlags *flags.Traffic, serviceName string) ([]servingv1.TrafficTarget, error) { err := verifyInputSanity(trafficFlags) if err != nil { return nil, err @@ -276,8 +279,17 @@ func Compute(cmd *cobra.Command, targets []servingv1.TrafficTarget, trafficFlags traffic := newServiceTraffic(targets) // First precedence: Untag revisions + var errTagNames []string for _, tag := range trafficFlags.UntagRevisions { - traffic.untagRevision(tag) + tagExists := traffic.untagRevision(tag, serviceName) + if !tagExists { + errTagNames = append(errTagNames, tag) + } + } + + // Return all errors from untagging revisions + if len(errTagNames) > 0 { + return nil, fmt.Errorf("tag(s) %s not present for any revisions of service %s", strings.Join(errTagNames, ", "), serviceName) } for _, each := range trafficFlags.RevisionsTags { diff --git a/pkg/kn/traffic/compute_test.go b/pkg/kn/traffic/compute_test.go index 470e5a590f..71262b300c 100644 --- a/pkg/kn/traffic/compute_test.go +++ b/pkg/kn/traffic/compute_test.go @@ -193,7 +193,7 @@ func TestCompute(t *testing.T) { testCmd, tFlags := newTestTrafficCommand() testCmd.SetArgs(testCase.inputFlags) testCmd.Execute() - targets, err := Compute(testCmd, testCase.existingTraffic, tFlags) + targets, err := Compute(testCmd, testCase.existingTraffic, tFlags, "serviceName") if err != nil { t.Fatal(err) } @@ -278,12 +278,24 @@ func TestComputeErrMsg(t *testing.T) { []string{"--traffic", "echo-v1=40", "--traffic", "echo-v1=60"}, "repetition of revision reference echo-v1 is not allowed, use only once with --traffic flag", }, + { + "untag single tag that does not exist", + append(newServiceTraffic([]servingv1.TrafficTarget{}), newTarget("latest", "echo-v1", 100, false)), + []string{"--untag", "foo"}, + "tag(s) foo not present for any revisions of service serviceName", + }, + { + "untag multiple tags that do not exist", + append(newServiceTraffic([]servingv1.TrafficTarget{}), newTarget("latest", "echo-v1", 100, false)), + []string{"--untag", "foo", "--untag", "bar"}, + "tag(s) foo, bar not present for any revisions of service serviceName", + }, } { t.Run(testCase.name, func(t *testing.T) { testCmd, tFlags := newTestTrafficCommand() testCmd.SetArgs(testCase.inputFlags) testCmd.Execute() - _, err := Compute(testCmd, testCase.existingTraffic, tFlags) + _, err := Compute(testCmd, testCase.existingTraffic, tFlags, "serviceName") assert.Error(t, err, testCase.errMsg) }) } diff --git a/test/e2e/service_test.go b/test/e2e/service_test.go index de49e6455a..900c5d3aeb 100644 --- a/test/e2e/service_test.go +++ b/test/e2e/service_test.go @@ -59,6 +59,10 @@ func TestService(t *testing.T) { t.Log("create service private and make public") serviceCreatePrivateUpdatePublic(r, "hello-private-public") + t.Log("error message from --untag with tag that doesn't exist") + test.ServiceCreate(r, "untag") + serviceUntagTagThatDoesNotExist(r, "untag") + t.Log("delete all services in a namespace") test.ServiceCreate(r, "svc1") test.ServiceCreate(r, "service2") @@ -140,6 +144,15 @@ func serviceMultipleDelete(r *test.KnRunResultCollector, existService, nonexistS assert.Check(r.T(), strings.Contains(out.Stdout, expectedErr), "Failed to get 'not found' error") } +func serviceUntagTagThatDoesNotExist(r *test.KnRunResultCollector, serviceName string) { + out := r.KnTest().Kn().Run("service", "list", serviceName) + r.AssertNoError(out) + assert.Check(r.T(), strings.Contains(out.Stdout, serviceName), "Service "+serviceName+" does not exist for test (but should exist)") + + out = r.KnTest().Kn().Run("service", "update", serviceName, "--untag", "foo", "--no-wait") + assert.Check(r.T(), util.ContainsAll(out.Stderr, "tag(s)", "foo", "not present", "service", "untag"), "Expected error message for using --untag with nonexistent tag") +} + func serviceDeleteAll(r *test.KnRunResultCollector) { out := r.KnTest().Kn().Run("service", "list") r.AssertNoError(out) diff --git a/test/e2e/traffic_split_test.go b/test/e2e/traffic_split_test.go index 53bcc0ecc5..ac1ee49bc6 100644 --- a/test/e2e/traffic_split_test.go +++ b/test/e2e/traffic_split_test.go @@ -105,7 +105,7 @@ func TestTrafficSplit(t *testing.T) { // make ordered fields per tflags (tag, revision, percent, latest) expectedTargets := []TargetFields{newTargetFields("v1", rev1, 50, false), newTargetFields("v2", rev2, 50, false)} - verifyTargets(r, serviceName, expectedTargets) + verifyTargets(r, serviceName, expectedTargets, false) test.ServiceDelete(r, serviceName) }, ) @@ -127,7 +127,7 @@ func TestTrafficSplit(t *testing.T) { test.ServiceUpdate(r, serviceName, "--traffic", fmt.Sprintf("%s=20,%s=80", rev1, rev2)) expectedTargets := []TargetFields{newTargetFields("", rev1, 20, false), newTargetFields("", rev2, 80, false)} - verifyTargets(r, serviceName, expectedTargets) + verifyTargets(r, serviceName, expectedTargets, false) test.ServiceDelete(r, serviceName) }, ) @@ -148,7 +148,7 @@ func TestTrafficSplit(t *testing.T) { test.ServiceUpdate(r, serviceName, "--tag", fmt.Sprintf("%s=%s", rev1, "candidate")) expectedTargets := []TargetFields{newTargetFields("", rev2, 100, true), newTargetFields("candidate", rev1, 0, false)} - verifyTargets(r, serviceName, expectedTargets) + verifyTargets(r, serviceName, expectedTargets, false) test.ServiceDelete(r, serviceName) }, ) @@ -171,7 +171,7 @@ func TestTrafficSplit(t *testing.T) { "--traffic", "candidate=2%,@latest=98%") expectedTargets := []TargetFields{newTargetFields("", rev2, 98, true), newTargetFields("candidate", rev1, 2, false)} - verifyTargets(r, serviceName, expectedTargets) + verifyTargets(r, serviceName, expectedTargets, false) test.ServiceDelete(r, serviceName) }, ) @@ -204,7 +204,7 @@ func TestTrafficSplit(t *testing.T) { // there will be 2 targets in existing block 1. @latest, 2.for revision $rev2 // target for rev1 is removed as it had no traffic and we untagged it's tag current expectedTargets := []TargetFields{newTargetFields("", rev3, 100, true), newTargetFields("current", rev2, 0, false)} - verifyTargets(r, serviceName, expectedTargets) + verifyTargets(r, serviceName, expectedTargets, false) test.ServiceDelete(r, serviceName) }, ) @@ -225,7 +225,7 @@ func TestTrafficSplit(t *testing.T) { test.ServiceUpdate(r, serviceName, "--untag", "testing", "--tag", "@latest=staging") expectedTargets := []TargetFields{newTargetFields("staging", rev1, 100, true)} - verifyTargets(r, serviceName, expectedTargets) + verifyTargets(r, serviceName, expectedTargets, false) test.ServiceDelete(r, serviceName) }, ) @@ -250,7 +250,7 @@ func TestTrafficSplit(t *testing.T) { expectedTargets := []TargetFields{newTargetFields("", rev2, 100, true), newTargetFields("staging", rev1, 0, false)} - verifyTargets(r, serviceName, expectedTargets) + verifyTargets(r, serviceName, expectedTargets, false) test.ServiceDelete(r, serviceName) }, ) @@ -277,7 +277,7 @@ func TestTrafficSplit(t *testing.T) { test.ServiceUpdate(r, serviceName, "--untag", "old", "--traffic", "@latest=100") expectedTargets := []TargetFields{newTargetFields("", rev2, 100, true)} - verifyTargets(r, serviceName, expectedTargets) + verifyTargets(r, serviceName, expectedTargets, false) test.ServiceDelete(r, serviceName) }, ) @@ -300,7 +300,7 @@ func TestTrafficSplit(t *testing.T) { "--traffic", "stable=50%,current=50%") expectedTargets := []TargetFields{newTargetFields("stable", rev1, 50, false), newTargetFields("current", rev1, 50, false)} - verifyTargets(r, serviceName, expectedTargets) + verifyTargets(r, serviceName, expectedTargets, false) test.ServiceDelete(r, serviceName) }, ) @@ -324,7 +324,7 @@ func TestTrafficSplit(t *testing.T) { test.ServiceUpdate(r, serviceName, "--traffic", "@latest=100") expectedTargets := []TargetFields{newTargetFields("", rev2, 100, true)} - verifyTargets(r, serviceName, expectedTargets) + verifyTargets(r, serviceName, expectedTargets, false) test.ServiceDelete(r, serviceName) }, ) @@ -343,7 +343,7 @@ func TestTrafficSplit(t *testing.T) { test.ServiceUpdate(r, serviceName, "--tag", "@latest=current") expectedTargets := []TargetFields{newTargetFields("current", rev1, 100, true)} - verifyTargets(r, serviceName, expectedTargets) + verifyTargets(r, serviceName, expectedTargets, false) test.ServiceDelete(r, serviceName) }, ) @@ -373,7 +373,7 @@ func TestTrafficSplit(t *testing.T) { expectedTargets := []TargetFields{newTargetFields("current", rev2, 0, true), newTargetFields("testing", rev1, 100, false)} - verifyTargets(r, serviceName, expectedTargets) + verifyTargets(r, serviceName, expectedTargets, false) test.ServiceDelete(r, serviceName) }, ) @@ -405,17 +405,74 @@ func TestTrafficSplit(t *testing.T) { // In spec of traffic block (not status) either latestReadyRevision:true or revisionName can be given per target newTargetFields("latest", rev2, 0, false)} - verifyTargets(r, serviceName, expectedTargets) + verifyTargets(r, serviceName, expectedTargets, false) + test.ServiceDelete(r, serviceName) + }, + ) + t.Run("UntagNonExistentTag", + func(t *testing.T) { + t.Log("use --untag on a tag that does not exist") + r := test.NewKnRunResultCollector(t, it) + defer r.DumpIfFailed() + + serviceName := test.GetNextServiceName(serviceBase) + rev1 := fmt.Sprintf("%s-rev-1", serviceName) + serviceCreateWithOptions(r, serviceName, "--revision-name", rev1) + + // existing state: a revision exist with latest tag + test.ServiceUpdate(r, serviceName, "--tag", fmt.Sprintf("%s=latest", rev1)) + + // desired state of revision tags: rev1=latest + // attempt to untag a tag that does not exist for the service's revisions + test.ServiceUpdateWithError(r, serviceName, "--untag", "foo") + + // state should remain the same as error from --untag will stop service update + expectedTargets := []TargetFields{ + newTargetFields("", rev1, 100, true), + newTargetFields("latest", rev1, 0, false), + } + + verifyTargets(r, serviceName, expectedTargets, true) + test.ServiceDelete(r, serviceName) + }, + ) + t.Run("UntagNonExistentTagAndValidTag", + func(t *testing.T) { + t.Log("use --untag on a tag that does not exist in addition to a tag that exists") + r := test.NewKnRunResultCollector(t, it) + defer r.DumpIfFailed() + + serviceName := test.GetNextServiceName(serviceBase) + rev1 := fmt.Sprintf("%s-rev-1", serviceName) + serviceCreateWithOptions(r, serviceName, "--revision-name", rev1) + + // existing state: a revision exist with latest tag + test.ServiceUpdate(r, serviceName, "--tag", fmt.Sprintf("%s=latest", rev1)) + + // desired state of revision tags: rev1=latest + // attempt to untag a tag that does not exist for the service's revisions (foo) + // and also untag a tag that exists (latest) + test.ServiceUpdateWithError(r, serviceName, "--untag", "latest", "--untag", "foo") + + // state should remain the same as error from --untag will stop service update + expectedTargets := []TargetFields{ + newTargetFields("", rev1, 100, true), + newTargetFields("latest", rev1, 0, false), + } + + verifyTargets(r, serviceName, expectedTargets, true) test.ServiceDelete(r, serviceName) }, ) } -func verifyTargets(r *test.KnRunResultCollector, serviceName string, expectedTargets []TargetFields) { +func verifyTargets(r *test.KnRunResultCollector, serviceName string, expectedTargets []TargetFields, expectErr bool) { out := test.ServiceDescribeWithJSONPath(r, serviceName, targetsJsonPath) assert.Check(r.T(), out != "") actualTargets, err := splitTargets(out, targetsSeparator, len(expectedTargets)) - assert.NilError(r.T(), err) + if !expectErr { + assert.NilError(r.T(), err) + } formattedActualTargets := formatActualTargets(r.T(), r.KnTest(), actualTargets) assert.DeepEqual(r.T(), expectedTargets, formattedActualTargets) if r.T().Failed() { diff --git a/vendor/modules.txt b/vendor/modules.txt index 8f7f05e1b5..9ebeaafe64 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -83,6 +83,7 @@ github.com/mailru/easyjson/buffer github.com/mailru/easyjson/jlexer github.com/mailru/easyjson/jwriter # github.com/mitchellh/go-homedir v1.1.0 +## explicit github.com/mitchellh/go-homedir # github.com/mitchellh/mapstructure v1.1.2 github.com/mitchellh/mapstructure @@ -108,13 +109,16 @@ github.com/spf13/afero/mem # github.com/spf13/cast v1.3.1 github.com/spf13/cast # github.com/spf13/cobra v0.0.6 => github.com/chmouel/cobra v0.0.0-20191021105835-a78788917390 +## explicit github.com/spf13/cobra github.com/spf13/cobra/doc # github.com/spf13/jwalterweatherman v1.1.0 github.com/spf13/jwalterweatherman # github.com/spf13/pflag v1.0.5 +## explicit github.com/spf13/pflag # github.com/spf13/viper v1.6.2 +## explicit github.com/spf13/viper # github.com/subosito/gotenv v1.2.0 github.com/subosito/gotenv @@ -130,6 +134,7 @@ go.uber.org/zap/internal/color go.uber.org/zap/internal/exit go.uber.org/zap/zapcore # golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 +## explicit golang.org/x/crypto/ssh/terminal # golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e golang.org/x/net/context @@ -184,12 +189,14 @@ gopkg.in/ini.v1 # gopkg.in/yaml.v2 v2.3.0 gopkg.in/yaml.v2 # gotest.tools v2.2.0+incompatible +## explicit gotest.tools/assert gotest.tools/assert/cmp gotest.tools/internal/difflib gotest.tools/internal/format gotest.tools/internal/source # k8s.io/api v0.17.4 => k8s.io/api v0.16.4 +## explicit k8s.io/api/admissionregistration/v1 k8s.io/api/admissionregistration/v1beta1 k8s.io/api/apps/v1 @@ -229,6 +236,7 @@ k8s.io/api/storage/v1 k8s.io/api/storage/v1alpha1 k8s.io/api/storage/v1beta1 # k8s.io/apimachinery v0.17.4 => k8s.io/apimachinery v0.16.4 +## explicit k8s.io/apimachinery/pkg/api/apitesting/fuzzer k8s.io/apimachinery/pkg/api/equality k8s.io/apimachinery/pkg/api/errors @@ -278,6 +286,7 @@ k8s.io/apimachinery/pkg/watch k8s.io/apimachinery/third_party/forked/golang/json k8s.io/apimachinery/third_party/forked/golang/reflect # k8s.io/cli-runtime v0.17.3 => k8s.io/cli-runtime v0.16.4 +## explicit k8s.io/cli-runtime/pkg/genericclioptions k8s.io/cli-runtime/pkg/kustomize k8s.io/cli-runtime/pkg/kustomize/k8sdeps @@ -291,6 +300,7 @@ k8s.io/cli-runtime/pkg/kustomize/k8sdeps/validator k8s.io/cli-runtime/pkg/printers k8s.io/cli-runtime/pkg/resource # k8s.io/client-go v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible => k8s.io/client-go v0.16.4 +## explicit k8s.io/client-go/discovery k8s.io/client-go/discovery/cached/disk k8s.io/client-go/dynamic @@ -462,6 +472,7 @@ k8s.io/utils/buffer k8s.io/utils/integer k8s.io/utils/trace # knative.dev/eventing v0.15.1-0.20200528220601-a61a6784a053 +## explicit knative.dev/eventing/pkg/apis/config knative.dev/eventing/pkg/apis/configs knative.dev/eventing/pkg/apis/configs/v1alpha1 @@ -488,6 +499,7 @@ knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha2 knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha2/fake knative.dev/eventing/pkg/logging # knative.dev/pkg v0.0.0-20200528142800-1c6815d7e4c9 +## explicit knative.dev/pkg/apis knative.dev/pkg/apis/duck knative.dev/pkg/apis/duck/v1 @@ -504,6 +516,7 @@ knative.dev/pkg/profiling knative.dev/pkg/ptr knative.dev/pkg/tracker # knative.dev/serving v0.15.1-0.20200601175503-4eab87b2ad07 +## explicit knative.dev/serving/pkg/apis/autoscaling knative.dev/serving/pkg/apis/autoscaling/v1alpha1 knative.dev/serving/pkg/apis/config @@ -541,4 +554,12 @@ sigs.k8s.io/kustomize/pkg/transformers/config sigs.k8s.io/kustomize/pkg/transformers/config/defaultconfig sigs.k8s.io/kustomize/pkg/types # sigs.k8s.io/yaml v1.2.0 +## explicit sigs.k8s.io/yaml +# github.com/spf13/cobra => github.com/chmouel/cobra v0.0.0-20191021105835-a78788917390 +# k8s.io/api => k8s.io/api v0.16.4 +# k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.16.4 +# k8s.io/apimachinery => k8s.io/apimachinery v0.16.4 +# k8s.io/cli-runtime => k8s.io/cli-runtime v0.16.4 +# k8s.io/client-go => k8s.io/client-go v0.16.4 +# k8s.io/code-generator => k8s.io/code-generator v0.16.4