From 2bc651236dd2cd1f0fc3aa75daba6fb653eae281 Mon Sep 17 00:00:00 2001 From: Tejal Desai Date: Wed, 14 Aug 2019 17:20:27 -0700 Subject: [PATCH 01/69] Remove time sensitive tests --- pkg/skaffold/deploy/status_check_test.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pkg/skaffold/deploy/status_check_test.go b/pkg/skaffold/deploy/status_check_test.go index 16c246d7410..6b63a395a1f 100644 --- a/pkg/skaffold/deploy/status_check_test.go +++ b/pkg/skaffold/deploy/status_check_test.go @@ -207,13 +207,6 @@ func TestPollDeploymentRolloutStatus(t *testing.T) { WithRunOutErr(rolloutCmd, "could not find", errors.New("deployment.apps/dep could not be found")), shouldErr: true, duration: 50, - }, { - description: "rollout returns success before time out", - command: testutil.NewFakeCmd(t). - WithRunOut(rolloutCmd, "Waiting for rollout to finish: 0 of 1 updated replicas are available..."). - WithRunOut(rolloutCmd, "Waiting for rollout to finish: 0 of 1 updated replicas are available..."). - WithRunOut(rolloutCmd, "deployment.apps/dep successfully rolled out"), - duration: 80, }, { description: "rollout returns did not stabilize within the given timeout", command: testutil.NewFakeCmd(t). From 093709ca00b7ae8df00ceb4a112e6826fa2e8a77 Mon Sep 17 00:00:00 2001 From: Nick Kubala Date: Thu, 15 Aug 2019 16:17:42 -0700 Subject: [PATCH 02/69] implement exponential backoff for retrieving cloud build status --- pkg/skaffold/build/gcb/cloud_build.go | 22 ++++++++++++++++++++-- pkg/skaffold/build/gcb/types.go | 19 +++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/pkg/skaffold/build/gcb/cloud_build.go b/pkg/skaffold/build/gcb/cloud_build.go index 1643a06ee43..cb9e17e9a72 100644 --- a/pkg/skaffold/build/gcb/cloud_build.go +++ b/pkg/skaffold/build/gcb/cloud_build.go @@ -22,6 +22,7 @@ import ( "fmt" "io" "net/http" + "strings" "time" cstorage "cloud.google.com/go/storage" @@ -40,6 +41,7 @@ import ( cloudbuild "google.golang.org/api/cloudbuild/v1" "google.golang.org/api/googleapi" "google.golang.org/api/iterator" + "k8s.io/apimachinery/pkg/util/wait" ) // Build builds a list of artifacts with Google Cloud Build. @@ -112,9 +114,25 @@ func (b *Builder) buildArtifactWithCloudBuild(ctx context.Context, out io.Writer offset := int64(0) watch: for { + var cb *cloudbuild.Build + var err error logrus.Debugf("current offset %d", offset) - cb, err := cbclient.Projects.Builds.Get(projectID, remoteID).Do() - if err != nil { + backoff := NewStatusBackoff() + if waitErr := wait.Poll(backoff.Duration, RetryTimeout, func() (bool, error) { + backoff.Step() + cb, err = cbclient.Projects.Builds.Get(projectID, remoteID).Do() + if err == nil { + return true, nil + } + if strings.Contains(err.Error(), "Quota exceeded") { + // if we hit the rate limit, continue to retry + return false, nil + } + return false, err + }); waitErr != nil { + return "", errors.Wrap(waitErr, "getting build status") + } + if cb == nil { return "", errors.Wrap(err, "getting build status") } diff --git a/pkg/skaffold/build/gcb/types.go b/pkg/skaffold/build/gcb/types.go index c6b73f82824..bbca7602148 100644 --- a/pkg/skaffold/build/gcb/types.go +++ b/pkg/skaffold/build/gcb/types.go @@ -29,6 +29,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/pkg/errors" + "k8s.io/apimachinery/pkg/util/wait" ) const ( @@ -58,8 +59,26 @@ const ( // RetryDelay is the time to wait in between polling the status of the cloud build RetryDelay = 1 * time.Second + + // BackoffFactor is the exponent for exponential backoff during build status polling + BackoffFactor = 1.5 + + // BackoffSteps is the number of times we increase the backoff time during exponential backoff + BackoffSteps = 10 + + // RetryTimeout is the max amount of time to retry getting the status of the build before erroring + RetryTimeout = 3 * time.Minute ) +func NewStatusBackoff() *wait.Backoff { + return &wait.Backoff{ + Duration: RetryDelay, + Factor: float64(BackoffFactor), + Steps: BackoffSteps, + Cap: 60 * time.Second, + } +} + // Builder builds artifacts with Google Cloud Build. type Builder struct { *latest.GoogleCloudBuild From 8669dd3492560c5886c5be32d3ceb289b11b8f69 Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Fri, 16 Aug 2019 14:25:59 -0700 Subject: [PATCH 03/69] Add owner.go to get top level owners of kubernetes objects --- pkg/skaffold/kubernetes/owner.go | 63 +++++++++ pkg/skaffold/kubernetes/owner_test.go | 189 ++++++++++++++++++++++++++ 2 files changed, 252 insertions(+) create mode 100644 pkg/skaffold/kubernetes/owner.go create mode 100644 pkg/skaffold/kubernetes/owner_test.go diff --git a/pkg/skaffold/kubernetes/owner.go b/pkg/skaffold/kubernetes/owner.go new file mode 100644 index 00000000000..a6b604e3fc0 --- /dev/null +++ b/pkg/skaffold/kubernetes/owner.go @@ -0,0 +1,63 @@ +/* +Copyright 2019 The Skaffold 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 kubernetes + +import ( + "fmt" + + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var ( + // For testing + getClientSet = GetClientset +) + +// TopLevelOwnerKey returns a key associated with the top level +// owner of a Kubernetes resource in the form Kind-Name +func TopLevelOwnerKey(obj metav1.Object, kind string) string { + for { + or := obj.GetOwnerReferences() + if or == nil { + return fmt.Sprintf("%s-%s", kind, obj.GetName()) + } + var err error + kind = or[0].Kind + obj, err = ownerMetaObject(obj.GetNamespace(), or[0]) + if err != nil { + logrus.Warnf("unable to get owner from reference: %v", or[0]) + return "" + } + } +} + +func ownerMetaObject(ns string, or metav1.OwnerReference) (metav1.Object, error) { + client, err := getClientSet() + if err != nil { + return nil, err + } + + switch or.Kind { + case "Deployment": + return client.AppsV1().Deployments(ns).Get(or.Name, metav1.GetOptions{}) + case "ReplicaSet": + return client.AppsV1().ReplicaSets(ns).Get(or.Name, metav1.GetOptions{}) + default: + return nil, fmt.Errorf("kind %s is not supported", or.Kind) + } +} diff --git a/pkg/skaffold/kubernetes/owner_test.go b/pkg/skaffold/kubernetes/owner_test.go new file mode 100644 index 00000000000..229ce1588a2 --- /dev/null +++ b/pkg/skaffold/kubernetes/owner_test.go @@ -0,0 +1,189 @@ +/* +Copyright 2019 The Skaffold 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 kubernetes + +import ( + "testing" + + v1 "k8s.io/api/core/v1" + + appsv1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + + "github.com/GoogleContainerTools/skaffold/testutil" + "k8s.io/client-go/kubernetes" + fakekubeclientset "k8s.io/client-go/kubernetes/fake" +) + +func mockClient(m kubernetes.Interface) func() (kubernetes.Interface, error) { + return func() (kubernetes.Interface, error) { + return m, nil + } +} + +func TestTopLevelOwnerKey(t *testing.T) { + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod", + Namespace: "ns", + OwnerReferences: []metav1.OwnerReference{ + { + Name: "rs", + Kind: "ReplicaSet", + }, + }, + }, + } + + rs := &appsv1.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rs", + Namespace: "ns", + OwnerReferences: []metav1.OwnerReference{ + { + Name: "dep", + Kind: "Deployment", + }, + }, + }, + } + + deployment := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "dep", + Namespace: "ns", + }, + } + + tests := []struct { + description string + initialObject metav1.Object + kind string + objects []runtime.Object + expected string + }{ + // { + // description: "owner is two levels up", + // initialObject: pod, + // kind: "Pod", + // objects: []runtime.Object{pod, rs, deployment}, + // expected: "Deployment-dep", + // }, + { + description: "object is owner", + initialObject: deployment, + kind: "Deployment", + objects: []runtime.Object{pod, rs, deployment}, + expected: "Deployment-dep", + }, + { + description: "error, owner doesn't exist", + initialObject: pod, + kind: "Pod", + objects: []runtime.Object{pod, rs}, + }, + } + + for _, test := range tests { + testutil.Run(t, test.description, func(t *testutil.T) { + client := fakekubeclientset.NewSimpleClientset(test.objects...) + t.Override(&getClientSet, mockClient(client)) + actual := TopLevelOwnerKey(test.initialObject, test.kind) + t.CheckDeepEqual(test.expected, actual) + }) + } +} + +func TestOwnerMetaObject(t *testing.T) { + tests := []struct { + description string + or metav1.OwnerReference + objects []runtime.Object + expected metav1.Object + }{ + { + description: "getting a deployment", + or: metav1.OwnerReference{ + Kind: "Deployment", + Name: "dep", + }, + objects: []runtime.Object{ + &v1.Service{}, + &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "dep", + Namespace: "ns", + }, + }, + &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "dep", + Namespace: "ns2", + }, + }, + }, + expected: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "dep", + Namespace: "ns", + }, + }, + }, { + description: "getting a replica set", + or: metav1.OwnerReference{ + Kind: "ReplicaSet", + Name: "rs", + }, + objects: []runtime.Object{ + &v1.Service{}, + &appsv1.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rs", + Namespace: "ns", + }, + }, + &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "dep", + Namespace: "ns2", + }, + }, + }, + expected: &appsv1.ReplicaSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rs", + Namespace: "ns", + }, + }, + }, + } + + for _, test := range tests { + testutil.Run(t, test.description, func(t *testutil.T) { + objs := make([]runtime.Object, len(test.objects)) + for i, s := range test.objects { + objs[i] = s + } + client := fakekubeclientset.NewSimpleClientset(objs...) + t.Override(&getClientSet, mockClient(client)) + actual, err := ownerMetaObject("ns", test.or) + t.CheckNoError(err) + t.CheckDeepEqual(test.expected, actual) + }) + } +} From 78824130be95fa20176035581bf8e4e2e31a86e4 Mon Sep 17 00:00:00 2001 From: Brian de Alwis Date: Fri, 16 Aug 2019 14:23:15 -0400 Subject: [PATCH 04/69] Configure jib.allowInsecureRegistries as required --- pkg/skaffold/build/gcb/jib.go | 4 +-- pkg/skaffold/build/local/jib_gradle.go | 4 +-- pkg/skaffold/build/local/jib_maven.go | 4 +-- pkg/skaffold/docker/remote.go | 8 ++--- pkg/skaffold/docker/remote_test.go | 44 ++++++++++++++++++++++++++ pkg/skaffold/jib/jib.go | 14 ++++++++ pkg/skaffold/jib/jib_gradle.go | 8 ++++- pkg/skaffold/jib/jib_gradle_test.go | 21 ++++++------ pkg/skaffold/jib/jib_maven.go | 6 +++- pkg/skaffold/jib/jib_maven_test.go | 27 +++++++++------- 10 files changed, 107 insertions(+), 33 deletions(-) create mode 100644 pkg/skaffold/docker/remote_test.go diff --git a/pkg/skaffold/build/gcb/jib.go b/pkg/skaffold/build/gcb/jib.go index f42415b064b..3f90509c370 100644 --- a/pkg/skaffold/build/gcb/jib.go +++ b/pkg/skaffold/build/gcb/jib.go @@ -29,7 +29,7 @@ func (b *Builder) jibMavenBuildSpec(artifact *latest.JibMavenArtifact, tag strin Steps: []*cloudbuild.BuildStep{{ Name: b.MavenImage, Entrypoint: "sh", - Args: fixHome("mvn", jib.GenerateMavenArgs("build", tag, artifact, b.skipTests)), + Args: fixHome("mvn", jib.GenerateMavenArgs("build", tag, artifact, b.skipTests, b.insecureRegistries)), }}, } } @@ -39,7 +39,7 @@ func (b *Builder) jibGradleBuildSpec(artifact *latest.JibGradleArtifact, tag str Steps: []*cloudbuild.BuildStep{{ Name: b.GradleImage, Entrypoint: "sh", - Args: fixHome("gradle", jib.GenerateGradleArgs("jib", tag, artifact, b.skipTests)), + Args: fixHome("gradle", jib.GenerateGradleArgs("jib", tag, artifact, b.skipTests, b.insecureRegistries)), }}, } } diff --git a/pkg/skaffold/build/local/jib_gradle.go b/pkg/skaffold/build/local/jib_gradle.go index 545772c6460..2578baf3607 100644 --- a/pkg/skaffold/build/local/jib_gradle.go +++ b/pkg/skaffold/build/local/jib_gradle.go @@ -36,7 +36,7 @@ func (b *Builder) buildJibGradle(ctx context.Context, out io.Writer, workspace s } func (b *Builder) buildJibGradleToDocker(ctx context.Context, out io.Writer, workspace string, artifact *latest.JibGradleArtifact, tag string) (string, error) { - args := jib.GenerateGradleArgs("jibDockerBuild", tag, artifact, b.skipTests) + args := jib.GenerateGradleArgs("jibDockerBuild", tag, artifact, b.skipTests, b.insecureRegistries) if err := b.runGradleCommand(ctx, out, workspace, args); err != nil { return "", err } @@ -45,7 +45,7 @@ func (b *Builder) buildJibGradleToDocker(ctx context.Context, out io.Writer, wor } func (b *Builder) buildJibGradleToRegistry(ctx context.Context, out io.Writer, workspace string, artifact *latest.JibGradleArtifact, tag string) (string, error) { - args := jib.GenerateGradleArgs("jib", tag, artifact, b.skipTests) + args := jib.GenerateGradleArgs("jib", tag, artifact, b.skipTests, b.insecureRegistries) if err := b.runGradleCommand(ctx, out, workspace, args); err != nil { return "", err } diff --git a/pkg/skaffold/build/local/jib_maven.go b/pkg/skaffold/build/local/jib_maven.go index 0e44964b1f8..e35309cd260 100644 --- a/pkg/skaffold/build/local/jib_maven.go +++ b/pkg/skaffold/build/local/jib_maven.go @@ -36,7 +36,7 @@ func (b *Builder) buildJibMaven(ctx context.Context, out io.Writer, workspace st } func (b *Builder) buildJibMavenToDocker(ctx context.Context, out io.Writer, workspace string, artifact *latest.JibMavenArtifact, tag string) (string, error) { - args := jib.GenerateMavenArgs("dockerBuild", tag, artifact, b.skipTests) + args := jib.GenerateMavenArgs("dockerBuild", tag, artifact, b.skipTests, b.insecureRegistries) if err := b.runMavenCommand(ctx, out, workspace, args); err != nil { return "", err } @@ -45,7 +45,7 @@ func (b *Builder) buildJibMavenToDocker(ctx context.Context, out io.Writer, work } func (b *Builder) buildJibMavenToRegistry(ctx context.Context, out io.Writer, workspace string, artifact *latest.JibMavenArtifact, tag string) (string, error) { - args := jib.GenerateMavenArgs("build", tag, artifact, b.skipTests) + args := jib.GenerateMavenArgs("build", tag, artifact, b.skipTests, b.insecureRegistries) if err := b.runMavenCommand(ctx, out, workspace, args); err != nil { return "", err } diff --git a/pkg/skaffold/docker/remote.go b/pkg/skaffold/docker/remote.go index c9879b0f760..ae616f377de 100644 --- a/pkg/skaffold/docker/remote.go +++ b/pkg/skaffold/docker/remote.go @@ -97,7 +97,7 @@ func remoteImage(identifier string, insecureRegistries map[string]bool) (v1.Imag return nil, errors.Wrapf(err, "parsing reference [%s]", identifier) } - if isInsecure(ref.Context().Registry.Name(), insecureRegistries) { + if IsInsecure(ref.Context().Registry.Name(), insecureRegistries) { ref, err = getInsecureRegistryImpl(identifier) if err != nil { logrus.Warnf("error getting insecure registry: %s\nremote references may not be retrieved", err.Error()) @@ -115,9 +115,9 @@ func getInsecureRegistry(identifier string) (name.Reference, error) { return ref, nil } -func isInsecure(ref string, insecureRegistries map[string]bool) bool { - _, ok := insecureRegistries[ref] - return ok +// IsInsecure tests if the registry is listed as an insecure registry; default is false +func IsInsecure(reg string, insecureRegistries map[string]bool) bool { + return insecureRegistries[reg] } func getRemoteImage(ref name.Reference) (v1.Image, error) { diff --git a/pkg/skaffold/docker/remote_test.go b/pkg/skaffold/docker/remote_test.go new file mode 100644 index 00000000000..8e5dbc8ed19 --- /dev/null +++ b/pkg/skaffold/docker/remote_test.go @@ -0,0 +1,44 @@ +/* +Copyright 2019 The Skaffold 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 docker + +import ( + "testing" + + "github.com/GoogleContainerTools/skaffold/testutil" +) + +func TestIsInsecure(t *testing.T) { + tests := []struct { + description string + registry string + insecureRegistries map[string]bool + result bool + }{ + {"nil registries", "localhost:5000", nil, false}, + {"unlisted registry", "other.tld", map[string]bool{"registry.tld": true}, false}, + {"listed insecure", "registry.tld", map[string]bool{"registry.tld": true}, true}, + {"listed secure", "registry.tld", map[string]bool{"registry.tld": false}, false}, + } + for _, test := range tests { + testutil.Run(t, test.description, func(t *testutil.T) { + result := IsInsecure(test.registry, test.insecureRegistries) + + t.CheckDeepEqual(test.result, result) + }) + } +} diff --git a/pkg/skaffold/jib/jib.go b/pkg/skaffold/jib/jib.go index 04062797718..b75f618ce4e 100644 --- a/pkg/skaffold/jib/jib.go +++ b/pkg/skaffold/jib/jib.go @@ -28,9 +28,11 @@ import ( "time" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" + "github.com/google/go-containerregistry/pkg/name" "github.com/karrick/godirwalk" "github.com/pkg/errors" "github.com/sirupsen/logrus" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" ) const ( @@ -229,3 +231,15 @@ func relativize(path string, roots ...string) (string, error) { } return "", errors.New("could not relativize path") } + +// isOnInsecureRegistry checks if the given image specifies an insecure registry +func isOnInsecureRegistry(image string, insecureRegistries map[string]bool) bool { + ref, err := name.ParseReference(image) + if err != nil { + // ignore the error as the image should have been validated before this + return false + } + + registry := ref.Context().Registry.Name() + return docker.IsInsecure(registry, insecureRegistries) +} diff --git a/pkg/skaffold/jib/jib_gradle.go b/pkg/skaffold/jib/jib_gradle.go index df1be577feb..071ac7b5498 100644 --- a/pkg/skaffold/jib/jib_gradle.go +++ b/pkg/skaffold/jib/jib_gradle.go @@ -51,11 +51,17 @@ func getCommandGradle(ctx context.Context, workspace string, a *latest.JibGradle } // GenerateGradleArgs generates the arguments to Gradle for building the project as an image. -func GenerateGradleArgs(task string, imageName string, a *latest.JibGradleArtifact, skipTests bool) []string { +func GenerateGradleArgs(task string, imageName string, a *latest.JibGradleArtifact, skipTests bool, insecureRegistries map[string]bool) []string { // disable jib's rich progress footer; we could use `--console=plain` // but it also disables colour which can be helpful args := []string{"-Djib.console=plain"} args = append(args, gradleCommand(a, task)...) + + if isOnInsecureRegistry(imageName, insecureRegistries) { + // jib doesn't support marking specific registries as insecure + args = append(args, "-Djib.allowInsecureRegistries=true") + } + args = append(args, "--image="+imageName) if skipTests { args = append(args, "-x", "test") diff --git a/pkg/skaffold/jib/jib_gradle_test.go b/pkg/skaffold/jib/jib_gradle_test.go index 9ae2467d949..9c7d7445d6b 100644 --- a/pkg/skaffold/jib/jib_gradle_test.go +++ b/pkg/skaffold/jib/jib_gradle_test.go @@ -164,18 +164,21 @@ func TestGetCommandGradle(t *testing.T) { func TestGenerateGradleArgs(t *testing.T) { tests := []struct { - in latest.JibGradleArtifact - skipTests bool - out []string + in latest.JibGradleArtifact + image string + skipTests bool + insecureRegistries map[string]bool + out []string }{ - {latest.JibGradleArtifact{}, false, []string{"-Djib.console=plain", "_skaffoldFailIfJibOutOfDate", "-Djib.requiredVersion=" + MinimumJibGradleVersion, ":task", "--image=image"}}, - {latest.JibGradleArtifact{Flags: []string{"-extra", "args"}}, false, []string{"-Djib.console=plain", "_skaffoldFailIfJibOutOfDate", "-Djib.requiredVersion=" + MinimumJibGradleVersion, ":task", "--image=image", "-extra", "args"}}, - {latest.JibGradleArtifact{}, true, []string{"-Djib.console=plain", "_skaffoldFailIfJibOutOfDate", "-Djib.requiredVersion=" + MinimumJibGradleVersion, ":task", "--image=image", "-x", "test"}}, - {latest.JibGradleArtifact{Project: "project"}, false, []string{"-Djib.console=plain", "_skaffoldFailIfJibOutOfDate", "-Djib.requiredVersion=" + MinimumJibGradleVersion, ":project:task", "--image=image"}}, - {latest.JibGradleArtifact{Project: "project"}, true, []string{"-Djib.console=plain", "_skaffoldFailIfJibOutOfDate", "-Djib.requiredVersion=" + MinimumJibGradleVersion, ":project:task", "--image=image", "-x", "test"}}, + {latest.JibGradleArtifact{}, "image", false, nil, []string{"-Djib.console=plain", "_skaffoldFailIfJibOutOfDate", "-Djib.requiredVersion=" + MinimumJibGradleVersion, ":task", "--image=image"}}, + {latest.JibGradleArtifact{Flags: []string{"-extra", "args"}}, "image", false, nil, []string{"-Djib.console=plain", "_skaffoldFailIfJibOutOfDate", "-Djib.requiredVersion=" + MinimumJibGradleVersion, ":task", "--image=image", "-extra", "args"}}, + {latest.JibGradleArtifact{}, "image", true, nil, []string{"-Djib.console=plain", "_skaffoldFailIfJibOutOfDate", "-Djib.requiredVersion=" + MinimumJibGradleVersion, ":task", "--image=image", "-x", "test"}}, + {latest.JibGradleArtifact{Project: "project"}, "image", false, nil, []string{"-Djib.console=plain", "_skaffoldFailIfJibOutOfDate", "-Djib.requiredVersion=" + MinimumJibGradleVersion, ":project:task", "--image=image"}}, + {latest.JibGradleArtifact{Project: "project"}, "image", true, nil, []string{"-Djib.console=plain", "_skaffoldFailIfJibOutOfDate", "-Djib.requiredVersion=" + MinimumJibGradleVersion, ":project:task", "--image=image", "-x", "test"}}, + {latest.JibGradleArtifact{Project: "project"}, "registry.tld/image", true, map[string]bool{"registry.tld": true}, []string{"-Djib.console=plain", "_skaffoldFailIfJibOutOfDate", "-Djib.requiredVersion=" + MinimumJibGradleVersion, ":project:task", "-Djib.allowInsecureRegistries=true", "--image=registry.tld/image", "-x", "test"}}, } for _, test := range tests { - command := GenerateGradleArgs("task", "image", &test.in, test.skipTests) + command := GenerateGradleArgs("task", test.image, &test.in, test.skipTests, test.insecureRegistries) testutil.CheckDeepEqual(t, test.out, command) } diff --git a/pkg/skaffold/jib/jib_maven.go b/pkg/skaffold/jib/jib_maven.go index 16de4e7a99f..c72e1deb3f0 100644 --- a/pkg/skaffold/jib/jib_maven.go +++ b/pkg/skaffold/jib/jib_maven.go @@ -51,7 +51,7 @@ func getCommandMaven(ctx context.Context, workspace string, a *latest.JibMavenAr } // GenerateMavenArgs generates the arguments to Maven for building the project as an image. -func GenerateMavenArgs(goal string, imageName string, a *latest.JibMavenArtifact, skipTests bool) []string { +func GenerateMavenArgs(goal string, imageName string, a *latest.JibMavenArtifact, skipTests bool, insecureRegistries map[string]bool) []string { // disable jib's rich progress footer on builds; we could use --batch-mode // but it also disables colour which can be helpful args := []string{"-Djib.console=plain"} @@ -69,6 +69,10 @@ func GenerateMavenArgs(goal string, imageName string, a *latest.JibMavenArtifact args = append(args, "package", "jib:"+goal, "-Djib.containerize="+a.Module) } + if isOnInsecureRegistry(imageName, insecureRegistries) { + // jib doesn't support marking specific registries as insecure + args = append(args, "-Djib.allowInsecureRegistries=true") + } args = append(args, "-Dimage="+imageName) return args diff --git a/pkg/skaffold/jib/jib_maven_test.go b/pkg/skaffold/jib/jib_maven_test.go index fd061ecee05..e3ee1e0e908 100644 --- a/pkg/skaffold/jib/jib_maven_test.go +++ b/pkg/skaffold/jib/jib_maven_test.go @@ -189,21 +189,24 @@ func TestGetCommandMaven(t *testing.T) { func TestGenerateMavenArgs(t *testing.T) { tests := []struct { - in latest.JibMavenArtifact - skipTests bool - out []string + in latest.JibMavenArtifact + image string + skipTests bool + insecureRegistries map[string]bool + out []string }{ - {latest.JibMavenArtifact{}, false, []string{"-Djib.console=plain", "jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=" + MinimumJibMavenVersion, "--non-recursive", "prepare-package", "jib:goal", "-Dimage=image"}}, - {latest.JibMavenArtifact{}, true, []string{"-Djib.console=plain", "jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=" + MinimumJibMavenVersion, "--non-recursive", "-DskipTests=true", "prepare-package", "jib:goal", "-Dimage=image"}}, - {latest.JibMavenArtifact{Profile: "profile"}, false, []string{"-Djib.console=plain", "jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=" + MinimumJibMavenVersion, "--activate-profiles", "profile", "--non-recursive", "prepare-package", "jib:goal", "-Dimage=image"}}, - {latest.JibMavenArtifact{Profile: "profile"}, true, []string{"-Djib.console=plain", "jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=" + MinimumJibMavenVersion, "--activate-profiles", "profile", "--non-recursive", "-DskipTests=true", "prepare-package", "jib:goal", "-Dimage=image"}}, - {latest.JibMavenArtifact{Module: "module"}, false, []string{"-Djib.console=plain", "jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=" + MinimumJibMavenVersion, "--projects", "module", "--also-make", "package", "jib:goal", "-Djib.containerize=module", "-Dimage=image"}}, - {latest.JibMavenArtifact{Module: "module"}, true, []string{"-Djib.console=plain", "jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=" + MinimumJibMavenVersion, "--projects", "module", "--also-make", "-DskipTests=true", "package", "jib:goal", "-Djib.containerize=module", "-Dimage=image"}}, - {latest.JibMavenArtifact{Module: "module", Profile: "profile"}, false, []string{"-Djib.console=plain", "jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=" + MinimumJibMavenVersion, "--activate-profiles", "profile", "--projects", "module", "--also-make", "package", "jib:goal", "-Djib.containerize=module", "-Dimage=image"}}, - {latest.JibMavenArtifact{Module: "module", Profile: "profile"}, true, []string{"-Djib.console=plain", "jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=" + MinimumJibMavenVersion, "--activate-profiles", "profile", "--projects", "module", "--also-make", "-DskipTests=true", "package", "jib:goal", "-Djib.containerize=module", "-Dimage=image"}}, + {latest.JibMavenArtifact{}, "image", false, nil, []string{"-Djib.console=plain", "jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=" + MinimumJibMavenVersion, "--non-recursive", "prepare-package", "jib:goal", "-Dimage=image"}}, + {latest.JibMavenArtifact{}, "image", true, nil, []string{"-Djib.console=plain", "jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=" + MinimumJibMavenVersion, "--non-recursive", "-DskipTests=true", "prepare-package", "jib:goal", "-Dimage=image"}}, + {latest.JibMavenArtifact{Profile: "profile"}, "image", false, nil, []string{"-Djib.console=plain", "jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=" + MinimumJibMavenVersion, "--activate-profiles", "profile", "--non-recursive", "prepare-package", "jib:goal", "-Dimage=image"}}, + {latest.JibMavenArtifact{Profile: "profile"}, "image", true, nil, []string{"-Djib.console=plain", "jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=" + MinimumJibMavenVersion, "--activate-profiles", "profile", "--non-recursive", "-DskipTests=true", "prepare-package", "jib:goal", "-Dimage=image"}}, + {latest.JibMavenArtifact{Module: "module"}, "image", false, nil, []string{"-Djib.console=plain", "jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=" + MinimumJibMavenVersion, "--projects", "module", "--also-make", "package", "jib:goal", "-Djib.containerize=module", "-Dimage=image"}}, + {latest.JibMavenArtifact{Module: "module"}, "image", true, nil, []string{"-Djib.console=plain", "jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=" + MinimumJibMavenVersion, "--projects", "module", "--also-make", "-DskipTests=true", "package", "jib:goal", "-Djib.containerize=module", "-Dimage=image"}}, + {latest.JibMavenArtifact{Module: "module", Profile: "profile"}, "image", false, nil, []string{"-Djib.console=plain", "jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=" + MinimumJibMavenVersion, "--activate-profiles", "profile", "--projects", "module", "--also-make", "package", "jib:goal", "-Djib.containerize=module", "-Dimage=image"}}, + {latest.JibMavenArtifact{Module: "module", Profile: "profile"}, "image", true, nil, []string{"-Djib.console=plain", "jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=" + MinimumJibMavenVersion, "--activate-profiles", "profile", "--projects", "module", "--also-make", "-DskipTests=true", "package", "jib:goal", "-Djib.containerize=module", "-Dimage=image"}}, + {latest.JibMavenArtifact{Module: "module", Profile: "profile"}, "registry.tld/image", true, map[string]bool{"registry.tld": true}, []string{"-Djib.console=plain", "jib:_skaffold-fail-if-jib-out-of-date", "-Djib.requiredVersion=" + MinimumJibMavenVersion, "--activate-profiles", "profile", "--projects", "module", "--also-make", "-DskipTests=true", "package", "jib:goal", "-Djib.containerize=module", "-Djib.allowInsecureRegistries=true", "-Dimage=registry.tld/image"}}, } for _, test := range tests { - args := GenerateMavenArgs("goal", "image", &test.in, test.skipTests) + args := GenerateMavenArgs("goal", test.image, &test.in, test.skipTests, test.insecureRegistries) testutil.CheckDeepEqual(t, test.out, args) } From 8e4495744b5484ac911de5b7269ad35bca6daa6d Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Fri, 16 Aug 2019 14:46:25 -0700 Subject: [PATCH 05/69] Add unit tests --- go.mod | 2 +- pkg/skaffold/kubernetes/owner_test.go | 16 +++++------ .../portforward/entry_manager_test.go | 4 +-- .../kubernetes/portforward/pod_forwarder.go | 8 +++--- .../portforward/pod_forwarder_test.go | 27 ++++++++++++------- .../portforward/port_forward_entry.go | 6 +++-- .../portforward/port_forward_entry_test.go | 8 +++--- .../portforward/port_forward_integration.go | 2 +- .../portforward/resource_forwarder.go | 2 +- .../portforward/resource_forwarder_test.go | 4 +-- 10 files changed, 45 insertions(+), 34 deletions(-) diff --git a/go.mod b/go.mod index 90cda333e0a..67d329eb50c 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( github.com/gorilla/mux v1.6.2 // indirect github.com/grpc-ecosystem/grpc-gateway v1.8.5 github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c // indirect - github.com/imdario/mergo v0.3.6 // indirect + github.com/imdario/mergo v0.3.6 github.com/karrick/godirwalk v1.7.5 github.com/knative/pkg v0.0.0-20190730155243-972acd413fb9 // indirect github.com/krishicks/yaml-patch v0.0.10 diff --git a/pkg/skaffold/kubernetes/owner_test.go b/pkg/skaffold/kubernetes/owner_test.go index 229ce1588a2..af1e70a8b65 100644 --- a/pkg/skaffold/kubernetes/owner_test.go +++ b/pkg/skaffold/kubernetes/owner_test.go @@ -77,21 +77,19 @@ func TestTopLevelOwnerKey(t *testing.T) { objects []runtime.Object expected string }{ - // { - // description: "owner is two levels up", - // initialObject: pod, - // kind: "Pod", - // objects: []runtime.Object{pod, rs, deployment}, - // expected: "Deployment-dep", - // }, { + description: "owner is two levels up", + initialObject: pod, + kind: "Pod", + objects: []runtime.Object{pod, rs, deployment}, + expected: "Deployment-dep", + }, { description: "object is owner", initialObject: deployment, kind: "Deployment", objects: []runtime.Object{pod, rs, deployment}, expected: "Deployment-dep", - }, - { + }, { description: "error, owner doesn't exist", initialObject: pod, kind: "Pod", diff --git a/pkg/skaffold/kubernetes/portforward/entry_manager_test.go b/pkg/skaffold/kubernetes/portforward/entry_manager_test.go index 8c78ecb5dd1..3ce39ec2a0f 100644 --- a/pkg/skaffold/kubernetes/portforward/entry_manager_test.go +++ b/pkg/skaffold/kubernetes/portforward/entry_manager_test.go @@ -52,13 +52,13 @@ func TestStop(t *testing.T) { Type: constants.Pod, Name: "resource", Namespace: "default", - }, "", "", "", 9000, false) + }, "", "", "", "", 9000, false) pfe2 := newPortForwardEntry(0, latest.PortForwardResource{ Type: constants.Pod, Name: "resource2", Namespace: "default", - }, "", "", "", 9001, false) + }, "", "", "", "", 9001, false) em := NewEntryManager(ioutil.Discard, nil) diff --git a/pkg/skaffold/kubernetes/portforward/pod_forwarder.go b/pkg/skaffold/kubernetes/portforward/pod_forwarder.go index 159a2bf9f57..6c585bc20ed 100644 --- a/pkg/skaffold/kubernetes/portforward/pod_forwarder.go +++ b/pkg/skaffold/kubernetes/portforward/pod_forwarder.go @@ -33,6 +33,7 @@ import ( var ( // For testing aggregatePodWatcher = kubernetes.AggregatePodWatcher + topLevelOwnerKey = kubernetes.TopLevelOwnerKey ) // WatchingPodForwarder is responsible for selecting pods satisfying a certain condition and port-forwarding the exposed @@ -101,6 +102,7 @@ func (p *WatchingPodForwarder) Start(ctx context.Context) error { } func (p *WatchingPodForwarder) portForwardPod(ctx context.Context, pod *v1.Pod) error { + ownerReference := topLevelOwnerKey(pod, pod.Kind) for _, c := range pod.Spec.Containers { for _, port := range c.Ports { // get current entry for this container @@ -112,7 +114,7 @@ func (p *WatchingPodForwarder) portForwardPod(ctx context.Context, pod *v1.Pod) LocalPort: int(port.ContainerPort), } - entry, err := p.podForwardingEntry(pod.ResourceVersion, c.Name, port.Name, resource) + entry, err := p.podForwardingEntry(pod.ResourceVersion, c.Name, port.Name, ownerReference, resource) if err != nil { return errors.Wrap(err, "getting pod forwarding entry") } @@ -132,12 +134,12 @@ func (p *WatchingPodForwarder) portForwardPod(ctx context.Context, pod *v1.Pod) return nil } -func (p *WatchingPodForwarder) podForwardingEntry(resourceVersion, containerName, portName string, resource latest.PortForwardResource) (*portForwardEntry, error) { +func (p *WatchingPodForwarder) podForwardingEntry(resourceVersion, containerName, portName, ownerReference string, resource latest.PortForwardResource) (*portForwardEntry, error) { rv, err := strconv.Atoi(resourceVersion) if err != nil { return nil, errors.Wrap(err, "converting resource version to integer") } - entry := newPortForwardEntry(rv, resource, resource.Name, containerName, portName, 0, true) + entry := newPortForwardEntry(rv, resource, resource.Name, containerName, portName, ownerReference, 0, true) // If we have, return the current entry oldEntry, ok := p.forwardedResources.Load(entry.key()) diff --git a/pkg/skaffold/kubernetes/portforward/pod_forwarder_test.go b/pkg/skaffold/kubernetes/portforward/pod_forwarder_test.go index fd5ce3ca1b2..ed30fe0b627 100644 --- a/pkg/skaffold/kubernetes/portforward/pod_forwarder_test.go +++ b/pkg/skaffold/kubernetes/portforward/pod_forwarder_test.go @@ -52,7 +52,7 @@ func TestAutomaticPortForwardPod(t *testing.T) { expectedPorts: map[int]struct{}{8080: {}}, availablePorts: []int{8080}, expectedEntries: map[string]*portForwardEntry{ - "containername-namespace-portname-8080": { + "owner-containername-namespace-portname-8080": { resourceVersion: 1, podName: "podname", containerName: "containername", @@ -63,6 +63,7 @@ func TestAutomaticPortForwardPod(t *testing.T) { Port: 8080, LocalPort: 8080, }, + ownerReference: "owner", automaticPodForwarding: true, portName: "portname", localPort: 8080, @@ -96,7 +97,7 @@ func TestAutomaticPortForwardPod(t *testing.T) { description: "unavailable container port", expectedPorts: map[int]struct{}{9000: {}}, expectedEntries: map[string]*portForwardEntry{ - "containername-namespace-portname-8080": { + "owner-containername-namespace-portname-8080": { resourceVersion: 1, podName: "podname", resource: latest.PortForwardResource{ @@ -106,6 +107,7 @@ func TestAutomaticPortForwardPod(t *testing.T) { Port: 8080, LocalPort: 8080, }, + ownerReference: "owner", automaticPodForwarding: true, containerName: "containername", portName: "portname", @@ -171,7 +173,7 @@ func TestAutomaticPortForwardPod(t *testing.T) { expectedPorts: map[int]struct{}{8080: {}, 50051: {}}, availablePorts: []int{8080, 50051}, expectedEntries: map[string]*portForwardEntry{ - "containername-namespace-portname-8080": { + "owner-containername-namespace-portname-8080": { resourceVersion: 1, podName: "podname", containerName: "containername", @@ -182,12 +184,13 @@ func TestAutomaticPortForwardPod(t *testing.T) { Port: 8080, LocalPort: 8080, }, + ownerReference: "owner", portName: "portname", automaticPodForwarding: true, localPort: 8080, terminationLock: &sync.Mutex{}, }, - "containername2-namespace2-portname2-50051": { + "owner-containername2-namespace2-portname2-50051": { resourceVersion: 1, podName: "podname2", containerName: "containername2", @@ -198,6 +201,7 @@ func TestAutomaticPortForwardPod(t *testing.T) { Port: 50051, LocalPort: 50051, }, + ownerReference: "owner", portName: "portname2", automaticPodForwarding: true, localPort: 50051, @@ -252,7 +256,7 @@ func TestAutomaticPortForwardPod(t *testing.T) { expectedPorts: map[int]struct{}{8080: {}, 9000: {}}, availablePorts: []int{8080, 9000}, expectedEntries: map[string]*portForwardEntry{ - "containername-namespace-portname-8080": { + "owner-containername-namespace-portname-8080": { resourceVersion: 1, podName: "podname", containerName: "containername", @@ -264,11 +268,12 @@ func TestAutomaticPortForwardPod(t *testing.T) { Port: 8080, LocalPort: 8080, }, + ownerReference: "owner", automaticPodForwarding: true, localPort: 8080, terminationLock: &sync.Mutex{}, }, - "containername2-namespace2-portname2-8080": { + "owner-containername2-namespace2-portname2-8080": { resourceVersion: 1, podName: "podname2", containerName: "containername2", @@ -280,6 +285,7 @@ func TestAutomaticPortForwardPod(t *testing.T) { Port: 8080, LocalPort: 8080, }, + ownerReference: "owner", automaticPodForwarding: true, localPort: 9000, terminationLock: &sync.Mutex{}, @@ -333,7 +339,7 @@ func TestAutomaticPortForwardPod(t *testing.T) { expectedPorts: map[int]struct{}{8080: {}}, availablePorts: []int{8080}, expectedEntries: map[string]*portForwardEntry{ - "containername-namespace-portname-8080": { + "owner-containername-namespace-portname-8080": { resourceVersion: 2, podName: "podname", containerName: "containername", @@ -345,6 +351,7 @@ func TestAutomaticPortForwardPod(t *testing.T) { Port: 8080, LocalPort: 8080, }, + ownerReference: "owner", automaticPodForwarding: true, localPort: 8080, terminationLock: &sync.Mutex{}, @@ -400,6 +407,7 @@ func TestAutomaticPortForwardPod(t *testing.T) { taken := map[int]struct{}{} t.Override(&retrieveAvailablePort, mockRetrieveAvailablePort(taken, test.availablePorts)) + t.Override(&topLevelOwnerKey, func(_ metav1.Object, _ string) string { return "owner" }) entryManager := EntryManager{ output: ioutil.Discard, @@ -425,7 +433,7 @@ func TestAutomaticPortForwardPod(t *testing.T) { actualForwardedResources := test.forwarder.forwardedResources.resources // cmp.Diff cannot access unexported fields, so use reflect.DeepEqual here directly if !reflect.DeepEqual(test.expectedEntries, actualForwardedResources) { - t.Errorf("Forwarded entries differs from expected entries. Expected: %s, Actual: %v", test.expectedEntries, actualForwardedResources) + t.Errorf("Forwarded entries differs from expected entries. Expected: %v, Actual: %v", test.expectedEntries, actualForwardedResources) } }) } @@ -475,6 +483,7 @@ func TestStartPodForwarder(t *testing.T) { }() return func() {}, nil }) + t.Override(&topLevelOwnerKey, func(_ metav1.Object, _ string) string { return "owner" }) imageList := kubernetes.NewImageList() imageList.Add("image") @@ -517,7 +526,7 @@ func TestStartPodForwarder(t *testing.T) { // wait for the pod resource to be forwarded err := wait.PollImmediate(10*time.Millisecond, 100*time.Millisecond, func() (bool, error) { - _, ok := fakeForwarder.forwardedResources.Load("mycontainer-default-myport-8080") + _, ok := fakeForwarder.forwardedResources.Load("owner-mycontainer-default-myport-8080") return ok, nil }) if err != nil && test.entryExpected { diff --git a/pkg/skaffold/kubernetes/portforward/port_forward_entry.go b/pkg/skaffold/kubernetes/portforward/port_forward_entry.go index bf2439ba6c4..17e0be6d6fd 100644 --- a/pkg/skaffold/kubernetes/portforward/port_forward_entry.go +++ b/pkg/skaffold/kubernetes/portforward/port_forward_entry.go @@ -30,6 +30,7 @@ type portForwardEntry struct { podName string containerName string portName string + ownerReference string localPort int automaticPodForwarding bool terminated bool @@ -38,13 +39,14 @@ type portForwardEntry struct { } // newPortForwardEntry returns a port forward entry. -func newPortForwardEntry(resourceVersion int, resource latest.PortForwardResource, podName, containerName, portName string, localPort int, automaticPodForwarding bool) *portForwardEntry { +func newPortForwardEntry(resourceVersion int, resource latest.PortForwardResource, podName, containerName, portName, ownerReference string, localPort int, automaticPodForwarding bool) *portForwardEntry { return &portForwardEntry{ resourceVersion: resourceVersion, resource: resource, podName: podName, containerName: containerName, portName: portName, + ownerReference: ownerReference, localPort: localPort, automaticPodForwarding: automaticPodForwarding, terminationLock: &sync.Mutex{}, @@ -56,7 +58,7 @@ func newPortForwardEntry(resourceVersion int, resource latest.PortForwardResourc // to be the same whenever pods restart func (p *portForwardEntry) key() string { if p.automaticPodForwarding { - return fmt.Sprintf("%s-%s-%s-%d", p.containerName, p.resource.Namespace, p.portName, p.resource.Port) + return fmt.Sprintf("%s-%s-%s-%s-%d", p.ownerReference, p.containerName, p.resource.Namespace, p.portName, p.resource.Port) } return fmt.Sprintf("%s-%s-%s-%d", p.resource.Type, p.resource.Name, p.resource.Namespace, p.resource.Port) } diff --git a/pkg/skaffold/kubernetes/portforward/port_forward_entry_test.go b/pkg/skaffold/kubernetes/portforward/port_forward_entry_test.go index 0e730bff31a..6d3237474ba 100644 --- a/pkg/skaffold/kubernetes/portforward/port_forward_entry_test.go +++ b/pkg/skaffold/kubernetes/portforward/port_forward_entry_test.go @@ -37,7 +37,7 @@ func TestPortForwardEntryKey(t *testing.T) { Name: "podName", Namespace: "default", Port: 8080, - }, "", "", "", 0, false), + }, "", "", "", "", 0, false), expected: "pod-podName-default-8080", }, { description: "entry for deploy", @@ -46,7 +46,7 @@ func TestPortForwardEntryKey(t *testing.T) { Name: "depName", Namespace: "namespace", Port: 9000, - }, "", "", "", 0, false), + }, "", "", "", "", 0, false), expected: "deployment-depName-namespace-9000", }, } @@ -79,8 +79,8 @@ func TestAutomaticPodForwardingKey(t *testing.T) { Name: "podName", Namespace: "default", Port: 8080, - }, "", "containerName", "portName", 0, true), - expected: "containerName-default-portName-8080", + }, "", "containerName", "portName", "owner", 0, true), + expected: "owner-containerName-default-portName-8080", }, } diff --git a/pkg/skaffold/kubernetes/portforward/port_forward_integration.go b/pkg/skaffold/kubernetes/portforward/port_forward_integration.go index fb6d885b183..6e41c5dfebe 100644 --- a/pkg/skaffold/kubernetes/portforward/port_forward_integration.go +++ b/pkg/skaffold/kubernetes/portforward/port_forward_integration.go @@ -42,7 +42,7 @@ func WhiteBoxPortForwardCycle(t *testing.T, kubectlCLI *kubectl.CLI, namespace s Name: "leeroy-web", Namespace: namespace, Port: 8080, - }, "", "dummy container", "", localPort, false) + }, "", "dummy container", "", "", localPort, false) defer em.Stop() em.forwardPortForwardEntry(ctx, pfe) em.Stop() diff --git a/pkg/skaffold/kubernetes/portforward/resource_forwarder.go b/pkg/skaffold/kubernetes/portforward/resource_forwarder.go index 985e275b527..608d08296aa 100644 --- a/pkg/skaffold/kubernetes/portforward/resource_forwarder.go +++ b/pkg/skaffold/kubernetes/portforward/resource_forwarder.go @@ -83,7 +83,7 @@ func (p *ResourceForwarder) portForwardResource(ctx context.Context, resource la func (p *ResourceForwarder) getCurrentEntry(resource latest.PortForwardResource) *portForwardEntry { // determine if we have seen this before - entry := newPortForwardEntry(0, resource, "", "", "", 0, false) + entry := newPortForwardEntry(0, resource, "", "", "", "", 0, false) // If we have, return the current entry oldEntry, ok := p.forwardedResources.Load(entry.key()) diff --git a/pkg/skaffold/kubernetes/portforward/resource_forwarder_test.go b/pkg/skaffold/kubernetes/portforward/resource_forwarder_test.go index 373b8921fac..0cb138eee13 100644 --- a/pkg/skaffold/kubernetes/portforward/resource_forwarder_test.go +++ b/pkg/skaffold/kubernetes/portforward/resource_forwarder_test.go @@ -161,7 +161,7 @@ func TestGetCurrentEntryFunc(t *testing.T) { Port: 8080, }, availablePorts: []int{8080}, - expected: newPortForwardEntry(0, latest.PortForwardResource{}, "", "", "", 8080, false), + expected: newPortForwardEntry(0, latest.PortForwardResource{}, "", "", "", "", 8080, false), }, { description: "port forward existing deployment", resource: latest.PortForwardResource{ @@ -181,7 +181,7 @@ func TestGetCurrentEntryFunc(t *testing.T) { localPort: 9000, }, }, - expected: newPortForwardEntry(0, latest.PortForwardResource{}, "", "", "", 9000, false), + expected: newPortForwardEntry(0, latest.PortForwardResource{}, "", "", "", "", 9000, false), }, } From 5534616c10a3a49a11c3215426daef9356f9c4dd Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Fri, 16 Aug 2019 15:06:29 -0700 Subject: [PATCH 06/69] Added more types of owners and unit tests --- go.sum | 1 + pkg/skaffold/kubernetes/owner.go | 10 +++ pkg/skaffold/kubernetes/owner_test.go | 103 ++++++++++++++++++++++++++ 3 files changed, 114 insertions(+) diff --git a/go.sum b/go.sum index 2333c9c8ee9..f4c26468483 100644 --- a/go.sum +++ b/go.sum @@ -402,6 +402,7 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.0.0-20190620073856-dcce3486da33 h1:aC/EvF9PT1h8NeMEOVwTel8xxbZwq0SZnxXNThEROnE= k8s.io/api v0.0.0-20190620073856-dcce3486da33/go.mod h1:ldk709UQo/iedNLOW7J06V9QSSGY5heETKeWqnPoqF8= +k8s.io/api v0.0.0-20190814101207-0772a1bdf941 h1:Y8yEkyPyJstRyZRD2qAVXeFfgilYKxdxB8zjO0cb/XY= k8s.io/apimachinery v0.0.0-20190620073744-d16981aedf33 h1:Lkd+QNFOB3DqrDyWo796aodJgFJautn/M+t9IGearPc= k8s.io/apimachinery v0.0.0-20190620073744-d16981aedf33/go.mod h1:9q5NW/mMno/nwbRZd/Ks2TECgi2PTZ9cwarf4q+ze6Q= k8s.io/client-go v0.0.0-20190620074045-585a16d2e773 h1:XyjDnwRO9icfyrN7HRSa8o3NqdPOEQoVW8vWizuqyQQ= diff --git a/pkg/skaffold/kubernetes/owner.go b/pkg/skaffold/kubernetes/owner.go index a6b604e3fc0..187c5c997ac 100644 --- a/pkg/skaffold/kubernetes/owner.go +++ b/pkg/skaffold/kubernetes/owner.go @@ -57,6 +57,16 @@ func ownerMetaObject(ns string, or metav1.OwnerReference) (metav1.Object, error) return client.AppsV1().Deployments(ns).Get(or.Name, metav1.GetOptions{}) case "ReplicaSet": return client.AppsV1().ReplicaSets(ns).Get(or.Name, metav1.GetOptions{}) + case "Job": + return client.BatchV1().Jobs(ns).Get(or.Name, metav1.GetOptions{}) + case "CronJob": + return client.BatchV1beta1().CronJobs(ns).Get(or.Name, metav1.GetOptions{}) + case "StatefulSet": + return client.AppsV1().StatefulSets(ns).Get(or.Name, metav1.GetOptions{}) + case "ReplicationController": + return client.CoreV1().ReplicationControllers(ns).Get(or.Name, metav1.GetOptions{}) + case "Pod": + return client.CoreV1().Pods(ns).Get(or.Name, metav1.GetOptions{}) default: return nil, fmt.Errorf("kind %s is not supported", or.Kind) } diff --git a/pkg/skaffold/kubernetes/owner_test.go b/pkg/skaffold/kubernetes/owner_test.go index af1e70a8b65..8b4fed1ad0b 100644 --- a/pkg/skaffold/kubernetes/owner_test.go +++ b/pkg/skaffold/kubernetes/owner_test.go @@ -21,6 +21,9 @@ import ( v1 "k8s.io/api/core/v1" + batchv1 "k8s.io/api/batch/v1" + batchv1beta1 "k8s.io/api/batch/v1beta1" + appsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -168,6 +171,106 @@ func TestOwnerMetaObject(t *testing.T) { Namespace: "ns", }, }, + }, { + description: "getting a job", + or: metav1.OwnerReference{ + Kind: "Job", + Name: "job", + }, + objects: []runtime.Object{ + &batchv1.Job{ + ObjectMeta: metav1.ObjectMeta{ + Name: "job", + Namespace: "ns", + }, + }, + }, + expected: &batchv1.Job{ + ObjectMeta: metav1.ObjectMeta{ + Name: "job", + Namespace: "ns", + }, + }, + }, { + description: "getting a cronjob", + or: metav1.OwnerReference{ + Kind: "CronJob", + Name: "cj", + }, + objects: []runtime.Object{ + &batchv1beta1.CronJob{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cj", + Namespace: "ns", + }, + }, + }, + expected: &batchv1beta1.CronJob{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cj", + Namespace: "ns", + }, + }, + }, { + description: "getting a statefulset", + or: metav1.OwnerReference{ + Kind: "StatefulSet", + Name: "ss", + }, + objects: []runtime.Object{ + &appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ss", + Namespace: "ns", + }, + }, + }, + expected: &appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ss", + Namespace: "ns", + }, + }, + }, { + description: "getting a replicationcontroller", + or: metav1.OwnerReference{ + Kind: "ReplicationController", + Name: "rc", + }, + objects: []runtime.Object{ + &v1.ReplicationController{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rc", + Namespace: "ns", + }, + }, + }, + expected: &v1.ReplicationController{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rc", + Namespace: "ns", + }, + }, + }, { + description: "getting a pod", + or: metav1.OwnerReference{ + Kind: "Pod", + Name: "po", + }, + objects: []runtime.Object{ + &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "po", + Namespace: "ns", + }, + }, + }, + expected: &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "po", + Namespace: "ns", + }, + }, }, } From c04682565367d02bbf87835597b46d706b309d44 Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Fri, 16 Aug 2019 17:09:10 -0700 Subject: [PATCH 07/69] review comment --- pkg/skaffold/kubernetes/owner.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pkg/skaffold/kubernetes/owner.go b/pkg/skaffold/kubernetes/owner.go index 187c5c997ac..d4b5e449afa 100644 --- a/pkg/skaffold/kubernetes/owner.go +++ b/pkg/skaffold/kubernetes/owner.go @@ -46,28 +46,28 @@ func TopLevelOwnerKey(obj metav1.Object, kind string) string { } } -func ownerMetaObject(ns string, or metav1.OwnerReference) (metav1.Object, error) { +func ownerMetaObject(ns string, owner metav1.OwnerReference) (metav1.Object, error) { client, err := getClientSet() if err != nil { return nil, err } - switch or.Kind { + switch owner.Kind { case "Deployment": - return client.AppsV1().Deployments(ns).Get(or.Name, metav1.GetOptions{}) + return client.AppsV1().Deployments(ns).Get(owner.Name, metav1.GetOptions{}) case "ReplicaSet": - return client.AppsV1().ReplicaSets(ns).Get(or.Name, metav1.GetOptions{}) + return client.AppsV1().ReplicaSets(ns).Get(owner.Name, metav1.GetOptions{}) case "Job": - return client.BatchV1().Jobs(ns).Get(or.Name, metav1.GetOptions{}) + return client.BatchV1().Jobs(ns).Get(owner.Name, metav1.GetOptions{}) case "CronJob": - return client.BatchV1beta1().CronJobs(ns).Get(or.Name, metav1.GetOptions{}) + return client.BatchV1beta1().CronJobs(ns).Get(owner.Name, metav1.GetOptions{}) case "StatefulSet": - return client.AppsV1().StatefulSets(ns).Get(or.Name, metav1.GetOptions{}) + return client.AppsV1().StatefulSets(ns).Get(owner.Name, metav1.GetOptions{}) case "ReplicationController": - return client.CoreV1().ReplicationControllers(ns).Get(or.Name, metav1.GetOptions{}) + return client.CoreV1().ReplicationControllers(ns).Get(owner.Name, metav1.GetOptions{}) case "Pod": - return client.CoreV1().Pods(ns).Get(or.Name, metav1.GetOptions{}) + return client.CoreV1().Pods(ns).Get(owner.Name, metav1.GetOptions{}) default: - return nil, fmt.Errorf("kind %s is not supported", or.Kind) + return nil, fmt.Errorf("kind %s is not supported", owner.Kind) } } From b46f34ff3830688b01bd29eebba64e5118e0d9c3 Mon Sep 17 00:00:00 2001 From: Cornelius Weig <22861411+corneliusweig@users.noreply.github.com> Date: Fri, 2 Aug 2019 12:57:35 +0200 Subject: [PATCH 08/69] docs: clarify that tagged images are not replaced in manifests Signed-off-by: Cornelius Weig <22861411+corneliusweig@users.noreply.github.com> --- docs/content/en/docs/how-tos/deployers/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/en/docs/how-tos/deployers/_index.md b/docs/content/en/docs/how-tos/deployers/_index.md index 41cfbb32875..f8eedf49a1f 100755 --- a/docs/content/en/docs/how-tos/deployers/_index.md +++ b/docs/content/en/docs/how-tos/deployers/_index.md @@ -9,7 +9,7 @@ to deploy your app to a Kubernetes cluster. When Skaffold deploys an application the following steps happen: -* the Skaffold deployer _renders_ the final kubernetes manifests: Skaffold replaces the image names in the kubernetes manifests with the final tagged image names. +* the Skaffold deployer _renders_ the final kubernetes manifests: Skaffold replaces untagged image names in the kubernetes manifests with the final tagged image names. Also, in case of the more complicated deployers the rendering step involves expanding templates (in case of helm) or calculating overlays (in case of kustomize). * the Skaffold deployer _deploys_ the final kubernetes manifests to the cluster From c6295fc5d1ba98d02e30d1cf48406c50882ff61a Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Mon, 19 Aug 2019 11:31:42 -0700 Subject: [PATCH 09/69] fix lint --- pkg/skaffold/kubernetes/owner_test.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pkg/skaffold/kubernetes/owner_test.go b/pkg/skaffold/kubernetes/owner_test.go index 8b4fed1ad0b..6f9a00283a3 100644 --- a/pkg/skaffold/kubernetes/owner_test.go +++ b/pkg/skaffold/kubernetes/owner_test.go @@ -276,11 +276,7 @@ func TestOwnerMetaObject(t *testing.T) { for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - objs := make([]runtime.Object, len(test.objects)) - for i, s := range test.objects { - objs[i] = s - } - client := fakekubeclientset.NewSimpleClientset(objs...) + client := fakekubeclientset.NewSimpleClientset(test.objects...) t.Override(&getClientSet, mockClient(client)) actual, err := ownerMetaObject("ns", test.or) t.CheckNoError(err) From a158b02939ac65e7b8924d1bc01a0192715954da Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Mon, 19 Aug 2019 13:38:36 -0700 Subject: [PATCH 10/69] Log a warning and rebuild if neededed when caching fails --- go.mod | 2 +- pkg/skaffold/build/cache/retrieve.go | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 90cda333e0a..67d329eb50c 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( github.com/gorilla/mux v1.6.2 // indirect github.com/grpc-ecosystem/grpc-gateway v1.8.5 github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c // indirect - github.com/imdario/mergo v0.3.6 // indirect + github.com/imdario/mergo v0.3.6 github.com/karrick/godirwalk v1.7.5 github.com/knative/pkg v0.0.0-20190730155243-972acd413fb9 // indirect github.com/krishicks/yaml-patch v0.0.10 diff --git a/pkg/skaffold/build/cache/retrieve.go b/pkg/skaffold/build/cache/retrieve.go index 5beb75a3a8c..2b49e59ed7c 100644 --- a/pkg/skaffold/build/cache/retrieve.go +++ b/pkg/skaffold/build/cache/retrieve.go @@ -28,6 +28,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/event" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" "github.com/pkg/errors" + "github.com/sirupsen/logrus" ) var ( @@ -62,7 +63,10 @@ func (c *cache) Build(ctx context.Context, out io.Writer, tags tag.ImageTags, ar result := results[i] switch result := result.(type) { case failed: - return nil, errors.Wrap(result.err, "checking cache") + logrus.Warnf("error checking cache, caching may not work as expected: %v", result.err) + color.Red.Fprintln(out, "Error checking cache. Rebuilding.") + needToBuild = append(needToBuild, artifact) + continue case needsBuilding: color.Red.Fprintln(out, "Not found. Building") @@ -114,11 +118,13 @@ func (c *cache) Build(ctx context.Context, out io.Writer, tags tag.ImageTags, ar } if err := c.addArtifacts(ctx, bRes, hashByName); err != nil { - return nil, errors.Wrap(err, "adding artifacts to cache") + logrus.Warnf("error adding artifacts to cache; caching may not work as expected: %v", err) + return append(bRes, alreadyBuilt...), nil } if err := saveArtifactCache(c.cacheFile, c.artifactCache); err != nil { - return nil, errors.Wrap(err, "saving cache") + logrus.Warnf("error saving cache file; caching may not work as expected: %v", err) + return append(bRes, alreadyBuilt...), nil } return append(bRes, alreadyBuilt...), err From 70c97ce2edf6060103bfcc317d91addedd450c34 Mon Sep 17 00:00:00 2001 From: Nick Kubala Date: Mon, 19 Aug 2019 15:31:45 -0700 Subject: [PATCH 11/69] more specific error message matching --- pkg/skaffold/build/gcb/cloud_build.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/skaffold/build/gcb/cloud_build.go b/pkg/skaffold/build/gcb/cloud_build.go index cb9e17e9a72..0bb7262db4e 100644 --- a/pkg/skaffold/build/gcb/cloud_build.go +++ b/pkg/skaffold/build/gcb/cloud_build.go @@ -124,7 +124,7 @@ watch: if err == nil { return true, nil } - if strings.Contains(err.Error(), "Quota exceeded") { + if strings.Contains(err.Error(), "Error 429: Quota exceeded for quota metric 'cloudbuild.googleapis.com/get_requests'") { // if we hit the rate limit, continue to retry return false, nil } From ab113c140165ba4e181fa3467136e5f75c7db472 Mon Sep 17 00:00:00 2001 From: Brian de Alwis Date: Tue, 20 Aug 2019 14:07:24 -0400 Subject: [PATCH 12/69] improve profile type mismatch log message to include field name --- pkg/skaffold/schema/profiles.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/skaffold/schema/profiles.go b/pkg/skaffold/schema/profiles.go index 9c5a8cd0706..a14d1867271 100644 --- a/pkg/skaffold/schema/profiles.go +++ b/pkg/skaffold/schema/profiles.go @@ -291,7 +291,7 @@ func overlayProfileField(config interface{}, profile interface{}) interface{} { } return v.Interface() default: - logrus.Warnf("unknown field type in profile overlay: %s. falling back to original config values", v.Kind()) + logrus.Warnf("Type mismatch in profile overlay for field %s of type %s; falling back to original config values", t.Name(), v.Kind()) return config } } From adfbee8d6283c911290cfc3955bfb210cd45587d Mon Sep 17 00:00:00 2001 From: Brian de Alwis Date: Tue, 20 Aug 2019 15:29:11 -0400 Subject: [PATCH 13/69] pass down field name --- pkg/skaffold/schema/profiles.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/skaffold/schema/profiles.go b/pkg/skaffold/schema/profiles.go index a14d1867271..db1409ef907 100644 --- a/pkg/skaffold/schema/profiles.go +++ b/pkg/skaffold/schema/profiles.go @@ -153,9 +153,9 @@ func applyProfile(config *latest.SkaffoldConfig, profile latest.Profile) error { APIVersion: config.APIVersion, Kind: config.Kind, Pipeline: latest.Pipeline{ - Build: overlayProfileField(config.Build, profile.Build).(latest.BuildConfig), - Deploy: overlayProfileField(config.Deploy, profile.Deploy).(latest.DeployConfig), - Test: overlayProfileField(config.Test, profile.Test).([]*latest.TestCase), + Build: overlayProfileField("Build", config.Build, profile.Build).(latest.BuildConfig), + Deploy: overlayProfileField("Deploy", config.Deploy, profile.Deploy).(latest.DeployConfig), + Test: overlayProfileField("Test", config.Test, profile.Test).([]*latest.TestCase), }, } @@ -256,16 +256,16 @@ func overlayStructField(config interface{}, profile interface{}) interface{} { for i := 0; i < profileValue.NumField(); i++ { fieldType := t.Field(i) - overlay := overlayProfileField(configValue.Field(i).Interface(), profileValue.Field(i).Interface()) + overlay := overlayProfileField(fieldType.Name, configValue.Field(i).Interface(), profileValue.Field(i).Interface()) finalConfig.Elem().FieldByName(fieldType.Name).Set(reflect.ValueOf(overlay)) } return reflect.Indirect(finalConfig).Interface() // since finalConfig is a pointer, dereference it } -func overlayProfileField(config interface{}, profile interface{}) interface{} { +func overlayProfileField(fieldName string, config interface{}, profile interface{}) interface{} { v := reflect.ValueOf(profile) // the profile itself t := reflect.TypeOf(profile) // the type of the profile, used for getting struct field types - logrus.Debugf("overlaying profile on config for field %s", t.Name()) + logrus.Debugf("overlaying profile on config for field %s", fieldName) switch v.Kind() { case reflect.Struct: // check the first field of the struct for a oneOf yamltag. @@ -291,7 +291,7 @@ func overlayProfileField(config interface{}, profile interface{}) interface{} { } return v.Interface() default: - logrus.Warnf("Type mismatch in profile overlay for field %s of type %s; falling back to original config values", t.Name(), v.Kind()) + logrus.Warnf("Type mismatch in profile overlay for field %s of type %s; falling back to original config values", fieldName, v.Kind()) return config } } From 12a80d4b1aadaf33ff8cd2de88b9ce0d7646cfc3 Mon Sep 17 00:00:00 2001 From: Brian de Alwis Date: Tue, 20 Aug 2019 16:14:31 -0400 Subject: [PATCH 14/69] Use struct field yaml names where possible --- pkg/skaffold/schema/profiles.go | 11 ++++++----- pkg/skaffold/yamltags/tags.go | 11 +++++++++++ pkg/skaffold/yamltags/tags_test.go | 11 +++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/pkg/skaffold/schema/profiles.go b/pkg/skaffold/schema/profiles.go index db1409ef907..d8e7e302645 100644 --- a/pkg/skaffold/schema/profiles.go +++ b/pkg/skaffold/schema/profiles.go @@ -27,6 +27,7 @@ import ( kubectx "github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/context" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/util" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/yamltags" yamlpatch "github.com/krishicks/yaml-patch" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -153,9 +154,9 @@ func applyProfile(config *latest.SkaffoldConfig, profile latest.Profile) error { APIVersion: config.APIVersion, Kind: config.Kind, Pipeline: latest.Pipeline{ - Build: overlayProfileField("Build", config.Build, profile.Build).(latest.BuildConfig), - Deploy: overlayProfileField("Deploy", config.Deploy, profile.Deploy).(latest.DeployConfig), - Test: overlayProfileField("Test", config.Test, profile.Test).([]*latest.TestCase), + Build: overlayProfileField("build", config.Build, profile.Build).(latest.BuildConfig), + Deploy: overlayProfileField("deploy", config.Deploy, profile.Deploy).(latest.DeployConfig), + Test: overlayProfileField("test", config.Test, profile.Test).([]*latest.TestCase), }, } @@ -256,7 +257,7 @@ func overlayStructField(config interface{}, profile interface{}) interface{} { for i := 0; i < profileValue.NumField(); i++ { fieldType := t.Field(i) - overlay := overlayProfileField(fieldType.Name, configValue.Field(i).Interface(), profileValue.Field(i).Interface()) + overlay := overlayProfileField(yamltags.YamlName(fieldType), configValue.Field(i).Interface(), profileValue.Field(i).Interface()) finalConfig.Elem().FieldByName(fieldType.Name).Set(reflect.ValueOf(overlay)) } return reflect.Indirect(finalConfig).Interface() // since finalConfig is a pointer, dereference it @@ -291,7 +292,7 @@ func overlayProfileField(fieldName string, config interface{}, profile interface } return v.Interface() default: - logrus.Warnf("Type mismatch in profile overlay for field %s of type %s; falling back to original config values", fieldName, v.Kind()) + logrus.Warnf("Type mismatch in profile overlay for field '%s' with type %s; falling back to original config values", fieldName, v.Kind()) return config } } diff --git a/pkg/skaffold/yamltags/tags.go b/pkg/skaffold/yamltags/tags.go index f59b31acf1e..42dd1092e6b 100644 --- a/pkg/skaffold/yamltags/tags.go +++ b/pkg/skaffold/yamltags/tags.go @@ -46,6 +46,17 @@ func ValidateStruct(s interface{}) error { return nil } +// YamlName returns the YAML name of the given field +func YamlName(field reflect.StructField) string { + if yamltags, ok := field.Tag.Lookup("yaml"); ok { + tags := strings.Split(yamltags, ",") + if len(tags) > 0 && tags[0] != "" { + return tags[0] + } + } + return field.Name +} + func processTags(yamltags string, val reflect.Value, parentStruct reflect.Value, field reflect.StructField) error { tags := strings.Split(yamltags, ",") for _, tag := range tags { diff --git a/pkg/skaffold/yamltags/tags_test.go b/pkg/skaffold/yamltags/tags_test.go index 321f01470b9..e0e94238d6c 100644 --- a/pkg/skaffold/yamltags/tags_test.go +++ b/pkg/skaffold/yamltags/tags_test.go @@ -186,3 +186,14 @@ func TestIsZeroValue(t *testing.T) { nonZeroMap := make(map[string]string) testutil.CheckDeepEqual(t, false, isZeroValue(reflect.ValueOf(nonZeroMap))) } + +func TestYamlName(t *testing.T) { + object := struct { + Empty string `yaml:",omitempty"` + Named string `yaml:"named,omitempty"` + Missing string + }{} + testutil.CheckDeepEqual(t, "Empty", YamlName(reflect.TypeOf(object).Field(0))) + testutil.CheckDeepEqual(t, "named", YamlName(reflect.TypeOf(object).Field(1))) + testutil.CheckDeepEqual(t, "Missing", YamlName(reflect.TypeOf(object).Field(2))) +} \ No newline at end of file From ee755e5ea97a88041cfc2c6c9ef820f6918141b4 Mon Sep 17 00:00:00 2001 From: Brian de Alwis Date: Wed, 21 Aug 2019 11:31:39 -0400 Subject: [PATCH 15/69] goimports --- pkg/skaffold/yamltags/tags.go | 2 +- pkg/skaffold/yamltags/tags_test.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/skaffold/yamltags/tags.go b/pkg/skaffold/yamltags/tags.go index 42dd1092e6b..b0f926628e1 100644 --- a/pkg/skaffold/yamltags/tags.go +++ b/pkg/skaffold/yamltags/tags.go @@ -52,7 +52,7 @@ func YamlName(field reflect.StructField) string { tags := strings.Split(yamltags, ",") if len(tags) > 0 && tags[0] != "" { return tags[0] - } + } } return field.Name } diff --git a/pkg/skaffold/yamltags/tags_test.go b/pkg/skaffold/yamltags/tags_test.go index e0e94238d6c..dc64eb0f9d1 100644 --- a/pkg/skaffold/yamltags/tags_test.go +++ b/pkg/skaffold/yamltags/tags_test.go @@ -189,11 +189,11 @@ func TestIsZeroValue(t *testing.T) { func TestYamlName(t *testing.T) { object := struct { - Empty string `yaml:",omitempty"` - Named string `yaml:"named,omitempty"` + Empty string `yaml:",omitempty"` + Named string `yaml:"named,omitempty"` Missing string }{} testutil.CheckDeepEqual(t, "Empty", YamlName(reflect.TypeOf(object).Field(0))) testutil.CheckDeepEqual(t, "named", YamlName(reflect.TypeOf(object).Field(1))) testutil.CheckDeepEqual(t, "Missing", YamlName(reflect.TypeOf(object).Field(2))) -} \ No newline at end of file +} From 0d1ab85aa9f293be62705ac6a3cf195788a50378 Mon Sep 17 00:00:00 2001 From: Brian de Alwis Date: Wed, 21 Aug 2019 11:33:54 -0400 Subject: [PATCH 16/69] goimports --- pkg/skaffold/jib/jib.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/skaffold/jib/jib.go b/pkg/skaffold/jib/jib.go index b75f618ce4e..38a78279a4b 100644 --- a/pkg/skaffold/jib/jib.go +++ b/pkg/skaffold/jib/jib.go @@ -27,12 +27,12 @@ import ( "strings" "time" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/google/go-containerregistry/pkg/name" "github.com/karrick/godirwalk" "github.com/pkg/errors" "github.com/sirupsen/logrus" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" ) const ( From d21227d05543055e436f489bacea55397253fdba Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Wed, 21 Aug 2019 14:34:38 -0700 Subject: [PATCH 17/69] Turn red messages yellow since we aren't erroring out, red is a bit aggressive. --- pkg/skaffold/build/cache/retrieve.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/skaffold/build/cache/retrieve.go b/pkg/skaffold/build/cache/retrieve.go index 2b49e59ed7c..8baaed5574c 100644 --- a/pkg/skaffold/build/cache/retrieve.go +++ b/pkg/skaffold/build/cache/retrieve.go @@ -64,12 +64,12 @@ func (c *cache) Build(ctx context.Context, out io.Writer, tags tag.ImageTags, ar switch result := result.(type) { case failed: logrus.Warnf("error checking cache, caching may not work as expected: %v", result.err) - color.Red.Fprintln(out, "Error checking cache. Rebuilding.") + color.Yellow.Fprintln(out, "Error checking cache. Rebuilding.") needToBuild = append(needToBuild, artifact) continue case needsBuilding: - color.Red.Fprintln(out, "Not found. Building") + color.Yellow.Fprintln(out, "Not found. Building") hashByName[artifact.ImageName] = result.hash needToBuild = append(needToBuild, artifact) continue From bd51465ea958f7e92038561c7e763c1c6a336503 Mon Sep 17 00:00:00 2001 From: Aaron Paz Date: Thu, 22 Aug 2019 09:46:14 -0700 Subject: [PATCH 18/69] Fix call to newPortForwardEntry constructor in kubectl_forwarder_test to fix build --- .../kubernetes/portforward/kubectl_forwarder_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/skaffold/kubernetes/portforward/kubectl_forwarder_test.go b/pkg/skaffold/kubernetes/portforward/kubectl_forwarder_test.go index 847dbe0c200..f2007deee79 100644 --- a/pkg/skaffold/kubernetes/portforward/kubectl_forwarder_test.go +++ b/pkg/skaffold/kubernetes/portforward/kubectl_forwarder_test.go @@ -55,7 +55,8 @@ func TestUnavailablePort(t *testing.T) { k := KubectlForwarder{ out: buf, } - pfe := newPortForwardEntry(0, latest.PortForwardResource{}, "", "", "", 8080, false) + pfe := newPortForwardEntry(0, latest.PortForwardResource{}, "", "", "", "", 8080, false) + k.Forward(context.Background(), pfe) // wait for isPortFree to be called @@ -77,7 +78,7 @@ func TestUnavailablePort(t *testing.T) { func TestTerminate(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) - pfe := newPortForwardEntry(0, latest.PortForwardResource{}, "", "", "", 8080, false) + pfe := newPortForwardEntry(0, latest.PortForwardResource{}, "", "", "", "", 8080, false) pfe.cancel = cancel k := &KubectlForwarder{} From a754602eaa00643d1f7ee7232685e715ec37b95e Mon Sep 17 00:00:00 2001 From: balopat Date: Thu, 22 Aug 2019 11:32:51 -0700 Subject: [PATCH 19/69] debug kubectl portforward --- pkg/skaffold/kubernetes/portforward/kubectl_forwarder.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/skaffold/kubernetes/portforward/kubectl_forwarder.go b/pkg/skaffold/kubernetes/portforward/kubectl_forwarder.go index 1722fa8bbad..c4937dac8fd 100644 --- a/pkg/skaffold/kubernetes/portforward/kubectl_forwarder.go +++ b/pkg/skaffold/kubernetes/portforward/kubectl_forwarder.go @@ -100,6 +100,7 @@ func (k *KubectlForwarder) forward(parentCtx context.Context, pfe *portForwardEn buf := &bytes.Buffer{} cmd := portForwardCmd(ctx, k.kubectl, pfe, buf) + logrus.Debugf("Running command: %s", cmd.Args) if err := cmd.Start(); err != nil { if ctx.Err() == context.Canceled { logrus.Debugf("couldn't start %v due to context cancellation", pfe) From 25d0ee1fac8465c3b51d178b7b30465f1d33e061 Mon Sep 17 00:00:00 2001 From: Tejal Desai Date: Thu, 22 Aug 2019 12:21:02 -0700 Subject: [PATCH 20/69] getting started --- DEVELOPMENT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 9f933c47e3b..70e1e134836 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -119,7 +119,7 @@ To build with your local changes you have two options: If you are iterating on skaffold and want to see your changes in action, you can: 1. [Build skaffold](#building-skaffold) -2. [Use the quickstart example](README.md#iterative-development) +2. [Use the quickstart example](examples/getting-started/README.md) ## Testing skaffold From c213d4f0a7b7c10bec759adb56ceccea5b587931 Mon Sep 17 00:00:00 2001 From: Brian de Alwis Date: Thu, 22 Aug 2019 15:54:25 -0400 Subject: [PATCH 21/69] return an error --- go.mod | 2 +- pkg/skaffold/jib/jib.go | 7 +++---- pkg/skaffold/jib/jib_gradle.go | 2 +- pkg/skaffold/jib/jib_maven.go | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 90cda333e0a..67d329eb50c 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( github.com/gorilla/mux v1.6.2 // indirect github.com/grpc-ecosystem/grpc-gateway v1.8.5 github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c // indirect - github.com/imdario/mergo v0.3.6 // indirect + github.com/imdario/mergo v0.3.6 github.com/karrick/godirwalk v1.7.5 github.com/knative/pkg v0.0.0-20190730155243-972acd413fb9 // indirect github.com/krishicks/yaml-patch v0.0.10 diff --git a/pkg/skaffold/jib/jib.go b/pkg/skaffold/jib/jib.go index 38a78279a4b..ac4137ede49 100644 --- a/pkg/skaffold/jib/jib.go +++ b/pkg/skaffold/jib/jib.go @@ -233,13 +233,12 @@ func relativize(path string, roots ...string) (string, error) { } // isOnInsecureRegistry checks if the given image specifies an insecure registry -func isOnInsecureRegistry(image string, insecureRegistries map[string]bool) bool { +func isOnInsecureRegistry(image string, insecureRegistries map[string]bool) (bool, error) { ref, err := name.ParseReference(image) if err != nil { - // ignore the error as the image should have been validated before this - return false + return false, err } registry := ref.Context().Registry.Name() - return docker.IsInsecure(registry, insecureRegistries) + return docker.IsInsecure(registry, insecureRegistries), nil } diff --git a/pkg/skaffold/jib/jib_gradle.go b/pkg/skaffold/jib/jib_gradle.go index 071ac7b5498..68a2cf86bd7 100644 --- a/pkg/skaffold/jib/jib_gradle.go +++ b/pkg/skaffold/jib/jib_gradle.go @@ -57,7 +57,7 @@ func GenerateGradleArgs(task string, imageName string, a *latest.JibGradleArtifa args := []string{"-Djib.console=plain"} args = append(args, gradleCommand(a, task)...) - if isOnInsecureRegistry(imageName, insecureRegistries) { + if insecure, err := isOnInsecureRegistry(imageName, insecureRegistries); err != nil && insecure { // jib doesn't support marking specific registries as insecure args = append(args, "-Djib.allowInsecureRegistries=true") } diff --git a/pkg/skaffold/jib/jib_maven.go b/pkg/skaffold/jib/jib_maven.go index c72e1deb3f0..2130a8c93ba 100644 --- a/pkg/skaffold/jib/jib_maven.go +++ b/pkg/skaffold/jib/jib_maven.go @@ -69,7 +69,7 @@ func GenerateMavenArgs(goal string, imageName string, a *latest.JibMavenArtifact args = append(args, "package", "jib:"+goal, "-Djib.containerize="+a.Module) } - if isOnInsecureRegistry(imageName, insecureRegistries) { + if insecure, err := isOnInsecureRegistry(imageName, insecureRegistries); err != nil && insecure { // jib doesn't support marking specific registries as insecure args = append(args, "-Djib.allowInsecureRegistries=true") } From 7d54a1f547bef1d04ddde8153c12a146fb0a7fb8 Mon Sep 17 00:00:00 2001 From: Dmitri Moore Date: Thu, 22 Aug 2019 16:18:10 -0700 Subject: [PATCH 22/69] Update cache-artifacts option usage language to reflect new default --- cmd/skaffold/app/cmd/flags.go | 2 +- docs/content/en/docs/references/cli/_index.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/skaffold/app/cmd/flags.go b/cmd/skaffold/app/cmd/flags.go index 6015d339498..565e24c7aab 100644 --- a/cmd/skaffold/app/cmd/flags.go +++ b/cmd/skaffold/app/cmd/flags.go @@ -82,7 +82,7 @@ var FlagRegistry = []Flag{ }, { Name: "cache-artifacts", - Usage: "Set to true to enable caching of artifacts", + Usage: "Set to false to disable default caching of artifacts", Value: &opts.CacheArtifacts, DefValue: true, FlagAddMethod: "BoolVar", diff --git a/docs/content/en/docs/references/cli/_index.md b/docs/content/en/docs/references/cli/_index.md index 5d37b48785e..742805f83ce 100644 --- a/docs/content/en/docs/references/cli/_index.md +++ b/docs/content/en/docs/references/cli/_index.md @@ -116,7 +116,7 @@ Examples: Options: -b, --build-image=[]: Choose which artifacts to build. Artifacts with image names that contain the expression will be built only. Default is to build sources for all artifacts - --cache-artifacts=true: Set to true to enable caching of artifacts + --cache-artifacts=false: Set to false to disable default caching of artifacts --cache-file='': Specify the location of the cache file (default $HOME/.skaffold/cache) -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config) -d, --default-repo='': Default repository value (overrides global config) @@ -287,7 +287,7 @@ Run a pipeline in debug mode Options: - --cache-artifacts=true: Set to true to enable caching of artifacts + --cache-artifacts=false: Set to false to disable default caching of artifacts --cache-file='': Specify the location of the cache file (default $HOME/.skaffold/cache) --cleanup=true: Delete deployments after dev or debug mode is interrupted -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config) @@ -429,7 +429,7 @@ Run a pipeline in development mode Options: - --cache-artifacts=true: Set to true to enable caching of artifacts + --cache-artifacts=false: Set to false to disable default caching of artifacts --cache-file='': Specify the location of the cache file (default $HOME/.skaffold/cache) --cleanup=true: Delete deployments after dev or debug mode is interrupted -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config) @@ -594,7 +594,7 @@ Examples: skaffold run -p Options: - --cache-artifacts=true: Set to true to enable caching of artifacts + --cache-artifacts=false: Set to false to disable default caching of artifacts --cache-file='': Specify the location of the cache file (default $HOME/.skaffold/cache) --cleanup=true: Delete deployments after dev or debug mode is interrupted -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config) From 5346c9f5b5d913c611c74149a7c2cddb1da3c231 Mon Sep 17 00:00:00 2001 From: Dmitri Moore Date: Fri, 23 Aug 2019 11:27:15 -0700 Subject: [PATCH 23/69] Revert manual changes from _index.md --- docs/content/en/docs/references/cli/_index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/content/en/docs/references/cli/_index.md b/docs/content/en/docs/references/cli/_index.md index 742805f83ce..5d37b48785e 100644 --- a/docs/content/en/docs/references/cli/_index.md +++ b/docs/content/en/docs/references/cli/_index.md @@ -116,7 +116,7 @@ Examples: Options: -b, --build-image=[]: Choose which artifacts to build. Artifacts with image names that contain the expression will be built only. Default is to build sources for all artifacts - --cache-artifacts=false: Set to false to disable default caching of artifacts + --cache-artifacts=true: Set to true to enable caching of artifacts --cache-file='': Specify the location of the cache file (default $HOME/.skaffold/cache) -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config) -d, --default-repo='': Default repository value (overrides global config) @@ -287,7 +287,7 @@ Run a pipeline in debug mode Options: - --cache-artifacts=false: Set to false to disable default caching of artifacts + --cache-artifacts=true: Set to true to enable caching of artifacts --cache-file='': Specify the location of the cache file (default $HOME/.skaffold/cache) --cleanup=true: Delete deployments after dev or debug mode is interrupted -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config) @@ -429,7 +429,7 @@ Run a pipeline in development mode Options: - --cache-artifacts=false: Set to false to disable default caching of artifacts + --cache-artifacts=true: Set to true to enable caching of artifacts --cache-file='': Specify the location of the cache file (default $HOME/.skaffold/cache) --cleanup=true: Delete deployments after dev or debug mode is interrupted -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config) @@ -594,7 +594,7 @@ Examples: skaffold run -p Options: - --cache-artifacts=false: Set to false to disable default caching of artifacts + --cache-artifacts=true: Set to true to enable caching of artifacts --cache-file='': Specify the location of the cache file (default $HOME/.skaffold/cache) --cleanup=true: Delete deployments after dev or debug mode is interrupted -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config) From 962d650a158e267577ff19aebbec1091bf550a73 Mon Sep 17 00:00:00 2001 From: Dmitri Moore Date: Fri, 23 Aug 2019 11:30:05 -0700 Subject: [PATCH 24/69] Commit results of running hack/generate-man.sh --- docs/content/en/docs/references/cli/_index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/content/en/docs/references/cli/_index.md b/docs/content/en/docs/references/cli/_index.md index 5d37b48785e..888c6c99be8 100644 --- a/docs/content/en/docs/references/cli/_index.md +++ b/docs/content/en/docs/references/cli/_index.md @@ -116,7 +116,7 @@ Examples: Options: -b, --build-image=[]: Choose which artifacts to build. Artifacts with image names that contain the expression will be built only. Default is to build sources for all artifacts - --cache-artifacts=true: Set to true to enable caching of artifacts + --cache-artifacts=true: Set to false to disable default caching of artifacts --cache-file='': Specify the location of the cache file (default $HOME/.skaffold/cache) -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config) -d, --default-repo='': Default repository value (overrides global config) @@ -287,7 +287,7 @@ Run a pipeline in debug mode Options: - --cache-artifacts=true: Set to true to enable caching of artifacts + --cache-artifacts=true: Set to false to disable default caching of artifacts --cache-file='': Specify the location of the cache file (default $HOME/.skaffold/cache) --cleanup=true: Delete deployments after dev or debug mode is interrupted -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config) @@ -429,7 +429,7 @@ Run a pipeline in development mode Options: - --cache-artifacts=true: Set to true to enable caching of artifacts + --cache-artifacts=true: Set to false to disable default caching of artifacts --cache-file='': Specify the location of the cache file (default $HOME/.skaffold/cache) --cleanup=true: Delete deployments after dev or debug mode is interrupted -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config) @@ -594,7 +594,7 @@ Examples: skaffold run -p Options: - --cache-artifacts=true: Set to true to enable caching of artifacts + --cache-artifacts=true: Set to false to disable default caching of artifacts --cache-file='': Specify the location of the cache file (default $HOME/.skaffold/cache) --cleanup=true: Delete deployments after dev or debug mode is interrupted -c, --config='': File for global configurations (defaults to $HOME/.skaffold/config) From 154fc3b8ed62e0cc7a7f4a77e2b7f797f2c25504 Mon Sep 17 00:00:00 2001 From: Taylor Barrella Date: Sun, 25 Aug 2019 22:34:36 -0700 Subject: [PATCH 25/69] Don't set KanikoArtifact if CustomArtifact is set Previously, it wasn't possible to use a custom in-cluster builder --- pkg/skaffold/schema/defaults/defaults.go | 5 +++- pkg/skaffold/schema/defaults/defaults_test.go | 27 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/pkg/skaffold/schema/defaults/defaults.go b/pkg/skaffold/schema/defaults/defaults.go index e7029881996..68601d62ae5 100644 --- a/pkg/skaffold/schema/defaults/defaults.go +++ b/pkg/skaffold/schema/defaults/defaults.go @@ -43,8 +43,11 @@ func Set(c *latest.SkaffoldConfig) error { ) if c.Build.Cluster != nil { - // All artifacts should be built with kaniko + // All artifacts should be built with kaniko or a custom command for _, a := range c.Build.Artifacts { + if a.CustomArtifact != nil { + continue + } setDefaultKanikoArtifact(a) setDefaultKanikoArtifactImage(a) setDefaultKanikoArtifactBuildContext(a) diff --git a/pkg/skaffold/schema/defaults/defaults_test.go b/pkg/skaffold/schema/defaults/defaults_test.go index dda45adefaa..197248bb6d8 100644 --- a/pkg/skaffold/schema/defaults/defaults_test.go +++ b/pkg/skaffold/schema/defaults/defaults_test.go @@ -115,6 +115,33 @@ func TestSetDefaultsOnCluster(t *testing.T) { }) } +func TestCustomBuildWithCluster(t *testing.T) { + cfg := &latest.SkaffoldConfig{ + Pipeline: latest.Pipeline{ + Build: latest.BuildConfig{ + Artifacts: []*latest.Artifact{ + { + ImageName: "image", + ArtifactType: latest.ArtifactType{ + CustomArtifact: &latest.CustomArtifact{ + BuildCommand: "./build.sh", + }, + }, + }, + }, + BuildType: latest.BuildType{ + Cluster: &latest.ClusterDetails{}, + }, + }, + }, + } + + err := Set(cfg) + + testutil.CheckError(t, false, err) + testutil.CheckDeepEqual(t, (*latest.KanikoArtifact)(nil), cfg.Build.Artifacts[0].KanikoArtifact) +} + func TestSetDefaultsOnCloudBuild(t *testing.T) { cfg := &latest.SkaffoldConfig{ Pipeline: latest.Pipeline{ From ded2b908888d71518d2cdc21587e7a556488d66d Mon Sep 17 00:00:00 2001 From: David Gageot Date: Mon, 26 Aug 2019 18:32:13 +0200 Subject: [PATCH 26/69] =?UTF-8?q?Don=E2=80=99t=20fetch=20images=20that=20a?= =?UTF-8?q?re=20aliases=20for=20scratch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #2718 Signed-off-by: David Gageot --- pkg/skaffold/docker/dependencies_test.go | 12 ++++++++++++ pkg/skaffold/docker/parse.go | 9 +++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/pkg/skaffold/docker/dependencies_test.go b/pkg/skaffold/docker/dependencies_test.go index f121e95599a..6afd5a96dc0 100644 --- a/pkg/skaffold/docker/dependencies_test.go +++ b/pkg/skaffold/docker/dependencies_test.go @@ -203,6 +203,12 @@ FROM jboss/wildfly:14.0.1.Final ADD ./file /etc/file ` +const fromScratchWithStageName = ` +FROM scratch as stage +FROM stage +ADD ./file /etc/file +` + type fakeImageFetcher struct{} func (f *fakeImageFetcher) fetch(image string, _ map[string]bool) (*v1.ConfigFile, error) { @@ -498,6 +504,12 @@ func TestGetDependencies(t *testing.T) { ignore: "**\n!server.go", expected: []string{"Dockerfile", "server.go"}, }, + { + description: "from scratch witch stage name", + dockerfile: fromScratchWithStageName, + workspace: ".", + expected: []string{"Dockerfile", "file"}, + }, } for _, test := range tests { diff --git a/pkg/skaffold/docker/parse.go b/pkg/skaffold/docker/parse.go index bd83e714cf0..7340d81496a 100644 --- a/pkg/skaffold/docker/parse.go +++ b/pkg/skaffold/docker/parse.go @@ -275,18 +275,15 @@ func readCopyCommand(value *parser.Node, envs []string, workdir string) (*copyCo } func expandOnbuildInstructions(nodes []*parser.Node, insecureRegistries map[string]bool) ([]*parser.Node, error) { - onbuildNodesCache := map[string][]*parser.Node{} + onbuildNodesCache := map[string][]*parser.Node{ + "scratch": nil, + } var expandedNodes []*parser.Node n := 0 for m, node := range nodes { if node.Value == command.From { from := fromInstruction(node) - // `scratch` is case insensitive - if strings.ToLower(from.image) == "scratch" { - continue - } - // onbuild should immediately follow the from command expandedNodes = append(expandedNodes, nodes[n:m+1]...) n = m + 1 From d45cce3fb454c4abaabf2411d6cdf68bd4189544 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Mon, 26 Aug 2019 18:59:40 +0200 Subject: [PATCH 27/69] =?UTF-8?q?Don=E2=80=99t=20store=20logs=20as=20mutab?= =?UTF-8?q?le=20slices=20of=20bytes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use immutable strings instead. Fixes #2669 Signed-off-by: David Gageot --- pkg/skaffold/build/parallel.go | 15 +++++++-------- pkg/skaffold/build/parallel_test.go | 6 +++--- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/pkg/skaffold/build/parallel.go b/pkg/skaffold/build/parallel.go index eca0b37742f..96698e7fd38 100644 --- a/pkg/skaffold/build/parallel.go +++ b/pkg/skaffold/build/parallel.go @@ -57,12 +57,12 @@ func InParallel(ctx context.Context, out io.Writer, tags tag.ImageTags, artifact defer cancel() results := new(sync.Map) - outputs := make([]chan []byte, len(artifacts)) + outputs := make([]chan string, len(artifacts)) // Run builds in // wg.Add(len(artifacts)) for i := range artifacts { - outputs[i] = make(chan []byte, buffSize) + outputs[i] = make(chan string, buffSize) r, w := io.Pipe() cw := setUpColorWriter(w, out) @@ -95,10 +95,10 @@ func runBuild(ctx context.Context, cw io.WriteCloser, tags tag.ImageTags, artifa cw.Close() } -func readOutputAndWriteToChannel(r io.Reader, lines chan []byte) { +func readOutputAndWriteToChannel(r io.Reader, lines chan string) { scanner := bufio.NewScanner(r) for scanner.Scan() { - lines <- scanner.Bytes() + lines <- scanner.Text() } close(lines) } @@ -119,7 +119,7 @@ func getBuildResult(ctx context.Context, cw io.Writer, tags tag.ImageTags, artif return build(ctx, cw, artifact, tag) } -func collectResults(out io.Writer, artifacts []*latest.Artifact, results *sync.Map, outputs []chan []byte) ([]Artifact, error) { +func collectResults(out io.Writer, artifacts []*latest.Artifact, results *sync.Map, outputs []chan string) ([]Artifact, error) { var built []Artifact for i, artifact := range artifacts { // Wait for build to complete. @@ -140,9 +140,8 @@ func collectResults(out io.Writer, artifacts []*latest.Artifact, results *sync.M return built, nil } -func printResult(out io.Writer, output chan []byte) { +func printResult(out io.Writer, output chan string) { for line := range output { - out.Write(line) - fmt.Fprintln(out) + fmt.Fprintln(out, line) } } diff --git a/pkg/skaffold/build/parallel_test.go b/pkg/skaffold/build/parallel_test.go index be6feca30b1..817836e0ef0 100644 --- a/pkg/skaffold/build/parallel_test.go +++ b/pkg/skaffold/build/parallel_test.go @@ -325,10 +325,10 @@ func TestColoredOutput(t *testing.T) { } } -func setUpChannels(n int) []chan []byte { - outputs := make([]chan []byte, n) +func setUpChannels(n int) []chan string { + outputs := make([]chan string, n) for i := 0; i < n; i++ { - outputs[i] = make(chan []byte, 10) + outputs[i] = make(chan string, 10) close(outputs[i]) } return outputs From a86172ecf3c81605607c0d46c409c2d6888f86b9 Mon Sep 17 00:00:00 2001 From: Brian de Alwis Date: Mon, 26 Aug 2019 15:25:01 -0400 Subject: [PATCH 28/69] fix inverted condition :blush: --- pkg/skaffold/jib/jib_gradle.go | 2 +- pkg/skaffold/jib/jib_maven.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/skaffold/jib/jib_gradle.go b/pkg/skaffold/jib/jib_gradle.go index 68a2cf86bd7..5e5923a8c42 100644 --- a/pkg/skaffold/jib/jib_gradle.go +++ b/pkg/skaffold/jib/jib_gradle.go @@ -57,7 +57,7 @@ func GenerateGradleArgs(task string, imageName string, a *latest.JibGradleArtifa args := []string{"-Djib.console=plain"} args = append(args, gradleCommand(a, task)...) - if insecure, err := isOnInsecureRegistry(imageName, insecureRegistries); err != nil && insecure { + if insecure, err := isOnInsecureRegistry(imageName, insecureRegistries); err == nil && insecure { // jib doesn't support marking specific registries as insecure args = append(args, "-Djib.allowInsecureRegistries=true") } diff --git a/pkg/skaffold/jib/jib_maven.go b/pkg/skaffold/jib/jib_maven.go index 2130a8c93ba..1ac7885d993 100644 --- a/pkg/skaffold/jib/jib_maven.go +++ b/pkg/skaffold/jib/jib_maven.go @@ -69,7 +69,7 @@ func GenerateMavenArgs(goal string, imageName string, a *latest.JibMavenArtifact args = append(args, "package", "jib:"+goal, "-Djib.containerize="+a.Module) } - if insecure, err := isOnInsecureRegistry(imageName, insecureRegistries); err != nil && insecure { + if insecure, err := isOnInsecureRegistry(imageName, insecureRegistries); err == nil && insecure { // jib doesn't support marking specific registries as insecure args = append(args, "-Djib.allowInsecureRegistries=true") } From 7399bc3d7a7315014f49a0c1b67f68c4029768b1 Mon Sep 17 00:00:00 2001 From: Marlon Gamez Date: Mon, 26 Aug 2019 14:40:43 -0700 Subject: [PATCH 29/69] check all artifacts for kaniko dependency --- pkg/skaffold/generate_pipeline/tasks.go | 44 +++++++++++++------------ 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/pkg/skaffold/generate_pipeline/tasks.go b/pkg/skaffold/generate_pipeline/tasks.go index bd376b9fbab..68d0f170fb6 100644 --- a/pkg/skaffold/generate_pipeline/tasks.go +++ b/pkg/skaffold/generate_pipeline/tasks.go @@ -76,30 +76,32 @@ func generateBuildTask(configFile *ConfigFile) (*tekton.Task, error) { }, } - // Add secret volume mounting for artifacts that need to be built with kaniko + // Add secret volume mounting if any artifacts in config need to be built with kaniko var volumes []corev1.Volume - if buildConfig.Artifacts[0].KanikoArtifact != nil { - volumes = []corev1.Volume{ - { - Name: kanikoSecretName, - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: kanikoSecretName, + for _, artifact := range buildConfig.Artifacts { + if artifact.KanikoArtifact != nil { + volumes = []corev1.Volume{ + { + Name: kanikoSecretName, + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: kanikoSecretName, + }, }, }, - }, - } - steps[0].VolumeMounts = []corev1.VolumeMount{ - { - Name: kanikoSecretName, - MountPath: "/secret", - }, - } - steps[0].Env = []corev1.EnvVar{ - { - Name: "GOOGLE_APPLICATION_CREDENTIALS", - Value: "/secret/" + kanikoSecretName, - }, + } + steps[0].VolumeMounts = []corev1.VolumeMount{ + { + Name: kanikoSecretName, + MountPath: "/secret", + }, + } + steps[0].Env = []corev1.EnvVar{ + { + Name: "GOOGLE_APPLICATION_CREDENTIALS", + Value: "/secret/" + kanikoSecretName, + }, + } } } From 42e217d5fac67f9295af575f10369c9b1489490f Mon Sep 17 00:00:00 2001 From: David Gageot Date: Mon, 26 Aug 2019 16:57:04 +0200 Subject: [PATCH 30/69] Simpler syntax Signed-off-by: David Gageot --- pkg/skaffold/build/cache/lookup_test.go | 4 ++-- pkg/skaffold/build/cache/retrieve_test.go | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/skaffold/build/cache/lookup_test.go b/pkg/skaffold/build/cache/lookup_test.go index 80aef350a12..6e68b816f30 100644 --- a/pkg/skaffold/build/cache/lookup_test.go +++ b/pkg/skaffold/build/cache/lookup_test.go @@ -93,7 +93,7 @@ func TestLookupLocal(t *testing.T) { t.Override(&hashForArtifact, func(context.Context, DependencyLister, *latest.Artifact) (string, error) { return "hash", nil }) - t.Override(&buildInProgress, func(_ string) {}) + t.Override(&buildInProgress, func(string) {}) cache := &cache{ imagesAreLocal: true, @@ -169,7 +169,7 @@ func TestLookupRemote(t *testing.T) { return "", errors.New("unknown remote tag") } }) - t.Override(&buildInProgress, func(_ string) {}) + t.Override(&buildInProgress, func(string) {}) cache := &cache{ imagesAreLocal: false, diff --git a/pkg/skaffold/build/cache/retrieve_test.go b/pkg/skaffold/build/cache/retrieve_test.go index 6da6766ab9c..beb7e17668a 100644 --- a/pkg/skaffold/build/cache/retrieve_test.go +++ b/pkg/skaffold/build/cache/retrieve_test.go @@ -91,8 +91,8 @@ func (t stubAuth) GetAllAuthConfigs() (map[string]types.AuthConfig, error) { ret func TestCacheBuildLocal(t *testing.T) { testutil.Run(t, "", func(t *testutil.T) { - t.Override(&buildComplete, func(_ string) {}) - t.Override(&buildInProgress, func(_ string) {}) + t.Override(&buildComplete, func(string) {}) + t.Override(&buildInProgress, func(string) {}) tmpDir := t.NewTempDir(). Write("dep1", "content1"). @@ -160,8 +160,8 @@ func TestCacheBuildLocal(t *testing.T) { func TestCacheBuildRemote(t *testing.T) { testutil.Run(t, "", func(t *testutil.T) { - t.Override(&buildComplete, func(_ string) {}) - t.Override(&buildInProgress, func(_ string) {}) + t.Override(&buildComplete, func(string) {}) + t.Override(&buildInProgress, func(string) {}) tmpDir := t.NewTempDir(). Write("dep1", "content1"). From dde545ad352acc43d52f03ad1c7a0543aabf93de Mon Sep 17 00:00:00 2001 From: David Gageot Date: Mon, 26 Aug 2019 16:57:41 +0200 Subject: [PATCH 31/69] Improve coverage Signed-off-by: David Gageot --- pkg/skaffold/build/cache/lookup.go | 3 +- pkg/skaffold/build/cache/lookup_test.go | 46 +++++++++++++++++++++---- pkg/skaffold/build/cache/retrieve.go | 2 +- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/pkg/skaffold/build/cache/lookup.go b/pkg/skaffold/build/cache/lookup.go index fe71ff5d15c..0e0ee2548c9 100644 --- a/pkg/skaffold/build/cache/lookup.go +++ b/pkg/skaffold/build/cache/lookup.go @@ -25,7 +25,6 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/event" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" - "github.com/pkg/errors" ) var ( @@ -56,7 +55,7 @@ func (c *cache) lookupArtifacts(ctx context.Context, tags tag.ImageTags, artifac func (c *cache) lookup(ctx context.Context, a *latest.Artifact, tag string) cacheDetails { hash, err := hashForArtifact(ctx, c.dependencies, a) if err != nil { - return failed{err: errors.Wrapf(err, "getting hash for artifact %s", a.ImageName)} + return failed{err: fmt.Errorf("getting hash for artifact %s: %v", a.ImageName, err)} } entry, cacheHit := c.artifactCache[hash] diff --git a/pkg/skaffold/build/cache/lookup_test.go b/pkg/skaffold/build/cache/lookup_test.go index 6e68b816f30..f881e759dc5 100644 --- a/pkg/skaffold/build/cache/lookup_test.go +++ b/pkg/skaffold/build/cache/lookup_test.go @@ -30,16 +30,24 @@ import ( func TestLookupLocal(t *testing.T) { tests := []struct { description string + hasher func(context.Context, DependencyLister, *latest.Artifact) (string, error) cache map[string]ImageDetails api *testutil.FakeAPIClient expected cacheDetails }{ { description: "miss", - expected: needsBuilding{hash: "hash"}, + hasher: mockHasher("thehash"), + expected: needsBuilding{hash: "thehash"}, + }, + { + description: "hash failure", + hasher: failingHasher("BUG"), + expected: failed{err: errors.New("getting hash for artifact artifact: BUG")}, }, { description: "miss no imageID", + hasher: mockHasher("hash"), cache: map[string]ImageDetails{ "hash": {Digest: "ignored"}, }, @@ -47,6 +55,7 @@ func TestLookupLocal(t *testing.T) { }, { description: "hit but not found", + hasher: mockHasher("hash"), cache: map[string]ImageDetails{ "hash": {ID: "imageID"}, }, @@ -55,6 +64,7 @@ func TestLookupLocal(t *testing.T) { }, { description: "hit but not found with error", + hasher: mockHasher("hash"), cache: map[string]ImageDetails{ "hash": {ID: "imageID"}, }, @@ -65,6 +75,7 @@ func TestLookupLocal(t *testing.T) { }, { description: "hit", + hasher: mockHasher("hash"), cache: map[string]ImageDetails{ "hash": {ID: "imageID"}, }, @@ -73,6 +84,7 @@ func TestLookupLocal(t *testing.T) { }, { description: "hit but different tag", + hasher: mockHasher("hash"), cache: map[string]ImageDetails{ "hash": {ID: "imageID"}, }, @@ -81,6 +93,7 @@ func TestLookupLocal(t *testing.T) { }, { description: "hit but imageID not found", + hasher: mockHasher("hash"), cache: map[string]ImageDetails{ "hash": {ID: "imageID"}, }, @@ -90,9 +103,7 @@ func TestLookupLocal(t *testing.T) { } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - t.Override(&hashForArtifact, func(context.Context, DependencyLister, *latest.Artifact) (string, error) { - return "hash", nil - }) + t.Override(&hashForArtifact, test.hasher) t.Override(&buildInProgress, func(string) {}) cache := &cache{ @@ -115,16 +126,24 @@ func TestLookupLocal(t *testing.T) { func TestLookupRemote(t *testing.T) { tests := []struct { description string + hasher func(context.Context, DependencyLister, *latest.Artifact) (string, error) cache map[string]ImageDetails api *testutil.FakeAPIClient expected cacheDetails }{ { description: "miss", + hasher: mockHasher("hash"), expected: needsBuilding{hash: "hash"}, }, + { + description: "hash failure", + hasher: failingHasher("BUG"), + expected: failed{err: errors.New("getting hash for artifact artifact: BUG")}, + }, { description: "hit", + hasher: mockHasher("hash"), cache: map[string]ImageDetails{ "hash": {Digest: "digest"}, }, @@ -132,6 +151,7 @@ func TestLookupRemote(t *testing.T) { }, { description: "hit with different tag", + hasher: mockHasher("hash"), cache: map[string]ImageDetails{ "hash": {Digest: "otherdigest"}, }, @@ -139,6 +159,7 @@ func TestLookupRemote(t *testing.T) { }, { description: "found locally", + hasher: mockHasher("hash"), cache: map[string]ImageDetails{ "hash": {ID: "imageID"}, }, @@ -147,6 +168,7 @@ func TestLookupRemote(t *testing.T) { }, { description: "not found", + hasher: mockHasher("hash"), cache: map[string]ImageDetails{ "hash": {ID: "imageID"}, }, @@ -156,9 +178,7 @@ func TestLookupRemote(t *testing.T) { } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - t.Override(&hashForArtifact, func(context.Context, DependencyLister, *latest.Artifact) (string, error) { - return "hash", nil - }) + t.Override(&hashForArtifact, test.hasher) t.Override(&docker.RemoteDigest, func(identifier string, _ map[string]bool) (string, error) { switch { case identifier == "tag": @@ -187,3 +207,15 @@ func TestLookupRemote(t *testing.T) { }) } } + +func mockHasher(value string) func(context.Context, DependencyLister, *latest.Artifact) (string, error) { + return func(context.Context, DependencyLister, *latest.Artifact) (string, error) { + return value, nil + } +} + +func failingHasher(errMessage string) func(context.Context, DependencyLister, *latest.Artifact) (string, error) { + return func(context.Context, DependencyLister, *latest.Artifact) (string, error) { + return "", errors.New(errMessage) + } +} diff --git a/pkg/skaffold/build/cache/retrieve.go b/pkg/skaffold/build/cache/retrieve.go index 8baaed5574c..ad1be619f11 100644 --- a/pkg/skaffold/build/cache/retrieve.go +++ b/pkg/skaffold/build/cache/retrieve.go @@ -70,7 +70,7 @@ func (c *cache) Build(ctx context.Context, out io.Writer, tags tag.ImageTags, ar case needsBuilding: color.Yellow.Fprintln(out, "Not found. Building") - hashByName[artifact.ImageName] = result.hash + hashByName[artifact.ImageName] = result.Hash() needToBuild = append(needToBuild, artifact) continue From 76be67d67d8ea943b4b189dfe104824bf2752f43 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Mon, 26 Aug 2019 17:09:06 +0200 Subject: [PATCH 32/69] More coverage Signed-off-by: David Gageot --- pkg/skaffold/kubectl/version.go | 3 +- pkg/skaffold/kubectl/version_test.go | 52 ++++++++++++++++------------ 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/pkg/skaffold/kubectl/version.go b/pkg/skaffold/kubectl/version.go index 3cc1841880b..bfe76ae4731 100644 --- a/pkg/skaffold/kubectl/version.go +++ b/pkg/skaffold/kubectl/version.go @@ -23,10 +23,9 @@ import ( "strconv" "strings" - "github.com/pkg/errors" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/warnings" + "github.com/pkg/errors" ) const unknown = "unknown" diff --git a/pkg/skaffold/kubectl/version_test.go b/pkg/skaffold/kubectl/version_test.go index f59cfea689f..9d0be318c52 100644 --- a/pkg/skaffold/kubectl/version_test.go +++ b/pkg/skaffold/kubectl/version_test.go @@ -20,44 +20,49 @@ import ( "context" "testing" - "github.com/pkg/errors" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/warnings" "github.com/GoogleContainerTools/skaffold/testutil" + "github.com/pkg/errors" ) func TestCheckVersion(t *testing.T) { tests := []struct { - description string - command util.Command - shouldErr bool - warnings []string + description string + command util.Command + shouldErr bool + warnings []string + expectedVersion string }{ { - description: "1.12 is valid", - command: testutil.FakeRunOut(t, "kubectl version --client -ojson", `{"clientVersion":{"major":"1","minor":"12"}}`), + description: "1.12 is valid", + command: testutil.FakeRunOut(t, "kubectl version --client -ojson", `{"clientVersion":{"major":"1","minor":"12"}}`), + expectedVersion: "1.12", }, { - description: "1.12+ is valid", - command: testutil.FakeRunOut(t, "kubectl version --client -ojson", `{"clientVersion":{"major":"1","minor":"12+"}}`), + description: "1.12+ is valid", + command: testutil.FakeRunOut(t, "kubectl version --client -ojson", `{"clientVersion":{"major":"1","minor":"12+"}}`), + expectedVersion: "1.12+", }, { - description: "1.11 is too old", - command: testutil.FakeRunOut(t, "kubectl version --client -ojson", `{"clientVersion":{"major":"1","minor":"11"}}`), - shouldErr: true, + description: "1.11 is too old", + command: testutil.FakeRunOut(t, "kubectl version --client -ojson", `{"clientVersion":{"major":"1","minor":"11"}}`), + shouldErr: true, + expectedVersion: "1.11", }, { - description: "invalid version", - command: testutil.FakeRunOut(t, "kubectl version --client -ojson", `not json`), - shouldErr: true, - warnings: []string{"unable to parse client version: invalid character 'o' in literal null (expecting 'u')"}, + description: "invalid version", + command: testutil.FakeRunOut(t, "kubectl version --client -ojson", `not json`), + shouldErr: true, + warnings: []string{"unable to parse client version: invalid character 'o' in literal null (expecting 'u')"}, + expectedVersion: "unknown", }, { - description: "cli not found", - command: testutil.FakeRunOutErr(t, "kubectl version --client -ojson", ``, errors.New("not found")), - shouldErr: true, - warnings: []string{"unable to get kubectl client version: not found"}, + description: "cli not found", + command: testutil.FakeRunOutErr(t, "kubectl version --client -ojson", ``, errors.New("not found")), + shouldErr: true, + warnings: []string{"unable to get kubectl client version: not found"}, + expectedVersion: "unknown", }, } for _, test := range tests { @@ -67,8 +72,11 @@ func TestCheckVersion(t *testing.T) { t.Override(&util.DefaultExecCommand, test.command) cli := CLI{} - err := cli.CheckVersion(context.Background()) + version := cli.Version(context.Background()).String() + t.CheckDeepEqual(test.expectedVersion, version) + + err := cli.CheckVersion(context.Background()) t.CheckErrorAndDeepEqual(test.shouldErr, err, test.warnings, fakeWarner.Warnings) }) } From 7392f91c8753237050e77e22447486af3494032d Mon Sep 17 00:00:00 2001 From: David Gageot Date: Mon, 26 Aug 2019 17:32:26 +0200 Subject: [PATCH 33/69] Panic instead of returning an error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we don’t know how to trigger an error. Signed-off-by: David Gageot --- pkg/skaffold/schema/v1alpha2/upgrade.go | 15 +++------ pkg/skaffold/schema/v1alpha3/upgrade.go | 14 +++----- pkg/skaffold/schema/v1alpha4/upgrade.go | 4 +-- pkg/skaffold/schema/v1alpha5/upgrade.go | 4 +-- pkg/skaffold/schema/v1beta1/upgrade.go | 4 +-- pkg/skaffold/schema/v1beta10/upgrade.go | 4 +-- pkg/skaffold/schema/v1beta11/upgrade.go | 4 +-- pkg/skaffold/schema/v1beta12/upgrade.go | 4 +-- pkg/skaffold/schema/v1beta2/upgrade.go | 4 +-- pkg/skaffold/schema/v1beta3/upgrade.go | 4 +-- pkg/skaffold/schema/v1beta4/upgrade.go | 4 +-- pkg/skaffold/schema/v1beta5/upgrade.go | 4 +-- pkg/skaffold/schema/v1beta6/upgrade.go | 43 ++++++++----------------- pkg/skaffold/schema/v1beta7/upgrade.go | 4 +-- pkg/skaffold/schema/v1beta8/upgrade.go | 26 ++++++--------- pkg/skaffold/schema/v1beta9/upgrade.go | 4 +-- pkg/skaffold/util/util.go | 28 +++++++++------- pkg/skaffold/util/util_test.go | 30 +++++++++++++++-- 18 files changed, 99 insertions(+), 105 deletions(-) diff --git a/pkg/skaffold/schema/v1alpha2/upgrade.go b/pkg/skaffold/schema/v1alpha2/upgrade.go index abb4783af84..06a9458cda9 100644 --- a/pkg/skaffold/schema/v1alpha2/upgrade.go +++ b/pkg/skaffold/schema/v1alpha2/upgrade.go @@ -20,7 +20,6 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/util" next "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" pkgutil "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" - "github.com/pkg/errors" ) // Upgrade upgrades a configuration to the next version. @@ -33,9 +32,8 @@ import ( func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { // convert Deploy (should be the same) var newDeploy next.DeployConfig - if err := pkgutil.CloneThroughJSON(config.Deploy, &newDeploy); err != nil { - return nil, errors.Wrap(err, "converting deploy config") - } + pkgutil.CloneThroughJSON(config.Deploy, &newDeploy) + // if the helm deploy config was set, then convert ValueFilePath to ValuesFiles if oldHelmDeploy := config.Deploy.DeployType.HelmDeploy; oldHelmDeploy != nil { for i, oldHelmRelease := range oldHelmDeploy.Releases { @@ -48,9 +46,7 @@ func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { // convert Profiles (should be the same) var newProfiles []next.Profile if config.Profiles != nil { - if err := pkgutil.CloneThroughJSON(config.Profiles, &newProfiles); err != nil { - return nil, errors.Wrap(err, "converting new profile") - } + pkgutil.CloneThroughJSON(config.Profiles, &newProfiles) } // if the helm deploy config was set for a profile, then convert ValueFilePath to ValuesFiles @@ -70,9 +66,8 @@ func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { // copy over old build config to new build config var newBuild next.BuildConfig - if err := pkgutil.CloneThroughJSON(config.Build, &newBuild); err != nil { - return nil, errors.Wrap(err, "converting new build") - } + pkgutil.CloneThroughJSON(config.Build, &newBuild) + // if the kaniko build was set, then convert it if oldKanikoBuilder != nil { newBuild.BuildType.KanikoBuild = &next.KanikoBuild{ diff --git a/pkg/skaffold/schema/v1alpha3/upgrade.go b/pkg/skaffold/schema/v1alpha3/upgrade.go index 278e8e8a4c0..1a19078df00 100644 --- a/pkg/skaffold/schema/v1alpha3/upgrade.go +++ b/pkg/skaffold/schema/v1alpha3/upgrade.go @@ -20,7 +20,6 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/util" next "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha4" pkgutil "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" - "github.com/pkg/errors" ) // Upgrade upgrades a configuration to the next version. @@ -43,16 +42,13 @@ import ( func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { // convert Deploy (should be the same) var newDeploy next.DeployConfig - if err := pkgutil.CloneThroughJSON(config.Deploy, &newDeploy); err != nil { - return nil, errors.Wrap(err, "converting deploy config") - } + pkgutil.CloneThroughJSON(config.Deploy, &newDeploy) // convert Profiles (should be the same) var newProfiles []next.Profile if config.Profiles != nil { - if err := pkgutil.CloneThroughJSON(config.Profiles, &newProfiles); err != nil { - return nil, errors.Wrap(err, "converting new profile") - } + pkgutil.CloneThroughJSON(config.Profiles, &newProfiles) + for i, oldProfile := range config.Profiles { convertBuild(oldProfile.Build, newProfiles[i].Build) } @@ -61,9 +57,7 @@ func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { // convert Build (should be the same) var newBuild next.BuildConfig oldBuild := config.Build - if err := pkgutil.CloneThroughJSON(oldBuild, &newBuild); err != nil { - return nil, errors.Wrap(err, "converting new build") - } + pkgutil.CloneThroughJSON(oldBuild, &newBuild) convertBuild(oldBuild, newBuild) return &next.SkaffoldConfig{ diff --git a/pkg/skaffold/schema/v1alpha4/upgrade.go b/pkg/skaffold/schema/v1alpha4/upgrade.go index c921170e88a..1f3a4c6c5ee 100644 --- a/pkg/skaffold/schema/v1alpha4/upgrade.go +++ b/pkg/skaffold/schema/v1alpha4/upgrade.go @@ -32,8 +32,8 @@ import ( func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { var newConfig next.SkaffoldConfig - err := pkgutil.CloneThroughJSON(config, &newConfig) + pkgutil.CloneThroughJSON(config, &newConfig) newConfig.APIVersion = next.Version - return &newConfig, err + return &newConfig, nil } diff --git a/pkg/skaffold/schema/v1alpha5/upgrade.go b/pkg/skaffold/schema/v1alpha5/upgrade.go index 6961e4d0e4f..29c78d1c6d3 100644 --- a/pkg/skaffold/schema/v1alpha5/upgrade.go +++ b/pkg/skaffold/schema/v1alpha5/upgrade.go @@ -44,8 +44,8 @@ func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { var newConfig next.SkaffoldConfig - err := pkgutil.CloneThroughJSON(config, &newConfig) + pkgutil.CloneThroughJSON(config, &newConfig) newConfig.APIVersion = next.Version - return &newConfig, err + return &newConfig, nil } diff --git a/pkg/skaffold/schema/v1beta1/upgrade.go b/pkg/skaffold/schema/v1beta1/upgrade.go index 7c1f645169d..c8a3d1b4f37 100644 --- a/pkg/skaffold/schema/v1beta1/upgrade.go +++ b/pkg/skaffold/schema/v1beta1/upgrade.go @@ -31,8 +31,8 @@ import ( func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { var newConfig next.SkaffoldConfig - err := pkgutil.CloneThroughJSON(config, &newConfig) + pkgutil.CloneThroughJSON(config, &newConfig) newConfig.APIVersion = next.Version - return &newConfig, err + return &newConfig, nil } diff --git a/pkg/skaffold/schema/v1beta10/upgrade.go b/pkg/skaffold/schema/v1beta10/upgrade.go index ffa447c3b06..49f29d87cea 100644 --- a/pkg/skaffold/schema/v1beta10/upgrade.go +++ b/pkg/skaffold/schema/v1beta10/upgrade.go @@ -31,8 +31,8 @@ import ( func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { var newConfig next.SkaffoldConfig - err := pkgutil.CloneThroughJSON(config, &newConfig) + pkgutil.CloneThroughJSON(config, &newConfig) newConfig.APIVersion = next.Version - return &newConfig, err + return &newConfig, nil } diff --git a/pkg/skaffold/schema/v1beta11/upgrade.go b/pkg/skaffold/schema/v1beta11/upgrade.go index 59f0ee8d98c..607f7014361 100644 --- a/pkg/skaffold/schema/v1beta11/upgrade.go +++ b/pkg/skaffold/schema/v1beta11/upgrade.go @@ -30,8 +30,8 @@ import ( func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { var newConfig next.SkaffoldConfig - err := pkgutil.CloneThroughJSON(config, &newConfig) + pkgutil.CloneThroughJSON(config, &newConfig) newConfig.APIVersion = next.Version - return &newConfig, err + return &newConfig, nil } diff --git a/pkg/skaffold/schema/v1beta12/upgrade.go b/pkg/skaffold/schema/v1beta12/upgrade.go index a5c7d5205a4..30db5cc6958 100755 --- a/pkg/skaffold/schema/v1beta12/upgrade.go +++ b/pkg/skaffold/schema/v1beta12/upgrade.go @@ -30,8 +30,8 @@ import ( func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { var newConfig next.SkaffoldConfig - err := pkgutil.CloneThroughJSON(config, &newConfig) + pkgutil.CloneThroughJSON(config, &newConfig) newConfig.APIVersion = next.Version - return &newConfig, err + return &newConfig, nil } diff --git a/pkg/skaffold/schema/v1beta2/upgrade.go b/pkg/skaffold/schema/v1beta2/upgrade.go index daa88868291..3e5dd00c3cc 100644 --- a/pkg/skaffold/schema/v1beta2/upgrade.go +++ b/pkg/skaffold/schema/v1beta2/upgrade.go @@ -33,8 +33,8 @@ import ( func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { var newConfig next.SkaffoldConfig - err := pkgutil.CloneThroughJSON(config, &newConfig) + pkgutil.CloneThroughJSON(config, &newConfig) newConfig.APIVersion = next.Version - return &newConfig, err + return &newConfig, nil } diff --git a/pkg/skaffold/schema/v1beta3/upgrade.go b/pkg/skaffold/schema/v1beta3/upgrade.go index e38ef8b8b13..0ce7c115423 100644 --- a/pkg/skaffold/schema/v1beta3/upgrade.go +++ b/pkg/skaffold/schema/v1beta3/upgrade.go @@ -33,8 +33,8 @@ import ( func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { var newConfig next.SkaffoldConfig - err := pkgutil.CloneThroughJSON(config, &newConfig) + pkgutil.CloneThroughJSON(config, &newConfig) newConfig.APIVersion = next.Version - return &newConfig, err + return &newConfig, nil } diff --git a/pkg/skaffold/schema/v1beta4/upgrade.go b/pkg/skaffold/schema/v1beta4/upgrade.go index 48e04c91325..f06da68f9ed 100644 --- a/pkg/skaffold/schema/v1beta4/upgrade.go +++ b/pkg/skaffold/schema/v1beta4/upgrade.go @@ -34,8 +34,8 @@ import ( func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { var newConfig next.SkaffoldConfig - err := pkgutil.CloneThroughJSON(config, &newConfig) + pkgutil.CloneThroughJSON(config, &newConfig) newConfig.APIVersion = next.Version - return &newConfig, err + return &newConfig, nil } diff --git a/pkg/skaffold/schema/v1beta5/upgrade.go b/pkg/skaffold/schema/v1beta5/upgrade.go index 82209e2e99c..8e0d2fa77a3 100644 --- a/pkg/skaffold/schema/v1beta5/upgrade.go +++ b/pkg/skaffold/schema/v1beta5/upgrade.go @@ -31,8 +31,8 @@ import ( func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { var newConfig next.SkaffoldConfig - err := pkgutil.CloneThroughJSON(config, &newConfig) + pkgutil.CloneThroughJSON(config, &newConfig) newConfig.APIVersion = next.Version - return &newConfig, err + return &newConfig, nil } diff --git a/pkg/skaffold/schema/v1beta6/upgrade.go b/pkg/skaffold/schema/v1beta6/upgrade.go index 31f31d37f70..5430103edf1 100644 --- a/pkg/skaffold/schema/v1beta6/upgrade.go +++ b/pkg/skaffold/schema/v1beta6/upgrade.go @@ -20,7 +20,6 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/util" next "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1beta7" pkgutil "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" - "github.com/pkg/errors" ) // Upgrade upgrades a configuration to the next version. @@ -34,39 +33,27 @@ import ( func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { // convert Deploy (should be the same) var newDeploy next.DeployConfig - if err := pkgutil.CloneThroughJSON(config.Deploy, &newDeploy); err != nil { - return nil, errors.Wrap(err, "converting deploy config") - } + pkgutil.CloneThroughJSON(config.Deploy, &newDeploy) // convert Profiles (should be the same) var newProfiles []next.Profile if config.Profiles != nil { - if err := pkgutil.CloneThroughJSON(config.Profiles, &newProfiles); err != nil { - return nil, errors.Wrap(err, "converting new profile") - } + pkgutil.CloneThroughJSON(config.Profiles, &newProfiles) } // Update profile if kaniko build exists for i, p := range config.Profiles { - if err := upgradeKanikoBuild(p.Build, &newProfiles[i].Build); err != nil { - return nil, errors.Wrap(err, "upgrading kaniko build") - } + upgradeKanikoBuild(p.Build, &newProfiles[i].Build) } // convert Kaniko if needed var newBuild next.BuildConfig - if err := pkgutil.CloneThroughJSON(config.Build, &newBuild); err != nil { - return nil, errors.Wrap(err, "converting new build") - } - if err := upgradeKanikoBuild(config.Build, &newBuild); err != nil { - return nil, errors.Wrap(err, "upgrading kaniko build") - } + pkgutil.CloneThroughJSON(config.Build, &newBuild) + upgradeKanikoBuild(config.Build, &newBuild) // convert Test (should be the same) var newTest []*next.TestCase - if err := pkgutil.CloneThroughJSON(config.Test, &newTest); err != nil { - return nil, errors.Wrap(err, "converting new test") - } + pkgutil.CloneThroughJSON(config.Test, &newTest) return &next.SkaffoldConfig{ APIVersion: next.Version, @@ -78,20 +65,16 @@ func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { }, nil } -func upgradeKanikoBuild(build BuildConfig, newConfig *next.BuildConfig) error { - if build.KanikoBuild == nil { - return nil - } +func upgradeKanikoBuild(build BuildConfig, newConfig *next.BuildConfig) { kaniko := build.KanikoBuild + if kaniko == nil { + return + } + // Else, transition values from old config to new config artifacts for _, a := range newConfig.Artifacts { - if err := pkgutil.CloneThroughJSON(kaniko, &a.KanikoArtifact); err != nil { - return errors.Wrap(err, "cloning kaniko artifact") - } + pkgutil.CloneThroughJSON(kaniko, &a.KanikoArtifact) } // Transition values from old config to in cluster details - if err := pkgutil.CloneThroughJSON(kaniko, &newConfig.Cluster); err != nil { - return errors.Wrap(err, "cloning cluster details") - } - return nil + pkgutil.CloneThroughJSON(kaniko, &newConfig.Cluster) } diff --git a/pkg/skaffold/schema/v1beta7/upgrade.go b/pkg/skaffold/schema/v1beta7/upgrade.go index 9192c27ab2d..930f1ecb731 100644 --- a/pkg/skaffold/schema/v1beta7/upgrade.go +++ b/pkg/skaffold/schema/v1beta7/upgrade.go @@ -31,8 +31,8 @@ import ( func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { var newConfig next.SkaffoldConfig - err := pkgutil.CloneThroughJSON(config, &newConfig) + pkgutil.CloneThroughJSON(config, &newConfig) newConfig.APIVersion = next.Version - return &newConfig, err + return &newConfig, nil } diff --git a/pkg/skaffold/schema/v1beta8/upgrade.go b/pkg/skaffold/schema/v1beta8/upgrade.go index 5bb839d16b5..4c30e646c3c 100644 --- a/pkg/skaffold/schema/v1beta8/upgrade.go +++ b/pkg/skaffold/schema/v1beta8/upgrade.go @@ -17,8 +17,6 @@ limitations under the License. package v1beta8 import ( - "github.com/pkg/errors" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/util" next "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1beta9" pkgutil "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" @@ -33,9 +31,7 @@ import ( func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { var newConfig next.SkaffoldConfig - if err := pkgutil.CloneThroughJSON(config, &newConfig); err != nil { - return nil, err - } + pkgutil.CloneThroughJSON(config, &newConfig) newConfig.APIVersion = next.Version if err := util.UpgradePipelines(config, &newConfig, upgradeOnePipeline); err != nil { @@ -55,16 +51,14 @@ func upgradeOnePipeline(oldPipeline, newPipeline interface{}) error { } if a.BuilderPlugin.Name == "bazel" { var ba *next.BazelArtifact - if err := pkgutil.CloneThroughYAML(a.BuilderPlugin.Properties, &ba); err != nil { - return errors.Wrap(err, "converting bazel artifact") - } + pkgutil.CloneThroughYAML(a.BuilderPlugin.Properties, &ba) + newBuild.Artifacts[i].BazelArtifact = ba } if a.BuilderPlugin.Name == "docker" { var da *next.DockerArtifact - if err := pkgutil.CloneThroughYAML(a.BuilderPlugin.Properties, &da); err != nil { - return errors.Wrap(err, "converting docker artifact") - } + pkgutil.CloneThroughYAML(a.BuilderPlugin.Properties, &da) + newBuild.Artifacts[i].DockerArtifact = da } } @@ -72,16 +66,14 @@ func upgradeOnePipeline(oldPipeline, newPipeline interface{}) error { if c := oldBuild.ExecutionEnvironment; c != nil { if c.Name == "googleCloudBuild" { var gcb *next.GoogleCloudBuild - if err := pkgutil.CloneThroughYAML(c.Properties, &gcb); err != nil { - return errors.Wrap(err, "converting gcb artifact") - } + pkgutil.CloneThroughYAML(c.Properties, &gcb) + newBuild.GoogleCloudBuild = gcb } if c.Name == "local" { var local *next.LocalBuild - if err := pkgutil.CloneThroughYAML(c.Properties, &local); err != nil { - return errors.Wrap(err, "converting local artifact") - } + pkgutil.CloneThroughYAML(c.Properties, &local) + newBuild.LocalBuild = local } } diff --git a/pkg/skaffold/schema/v1beta9/upgrade.go b/pkg/skaffold/schema/v1beta9/upgrade.go index 5291e4edec7..525560c3dfc 100644 --- a/pkg/skaffold/schema/v1beta9/upgrade.go +++ b/pkg/skaffold/schema/v1beta9/upgrade.go @@ -46,9 +46,7 @@ var ( func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { var newConfig next.SkaffoldConfig - if err := pkgutil.CloneThroughJSON(config, &newConfig); err != nil { - return nil, err - } + pkgutil.CloneThroughJSON(config, &newConfig) newConfig.APIVersion = next.Version if err := util.UpgradePipelines(config, &newConfig, upgradeOnePipeline); err != nil { diff --git a/pkg/skaffold/util/util.go b/pkg/skaffold/util/util.go index b9dcc16873f..e1ea58cb734 100644 --- a/pkg/skaffold/util/util.go +++ b/pkg/skaffold/util/util.go @@ -234,28 +234,34 @@ func NonEmptyLines(input []byte) []string { return result } -// CloneThroughJSON marshals the old interface into the new one -func CloneThroughJSON(old interface{}, new interface{}) error { +// CloneThroughJSON clones an `old` object into a `new` one +// using json marshalling and unmarshalling. +// Since the object can be marshalled, it's almost sure it can be +// unmarshalled. So we prefer to panic instead of returning an error +// that would create an untestable branch on the call site. +func CloneThroughJSON(old interface{}, new interface{}) { o, err := json.Marshal(old) if err != nil { - return errors.Wrap(err, "marshalling old") + panic(fmt.Sprintf("marshalling old: %v", err)) } - if err := json.Unmarshal(o, &new); err != nil { - return errors.Wrap(err, "unmarshalling new") + if err := json.Unmarshal(o, new); err != nil { + panic(fmt.Sprintf("unmarshalling new: %v", err)) } - return nil } -// CloneThroughYAML marshals the old interface into the new one -func CloneThroughYAML(old interface{}, new interface{}) error { +// CloneThroughYAML clones an `old` object into a `new` one +// using yaml marshalling and unmarshalling. +// Since the object can be marshalled, it's almost sure it can be +// unmarshalled. So we prefer to panic instead of returning an error +// that would create an untestable branch on the call site. +func CloneThroughYAML(old interface{}, new interface{}) { contents, err := yaml.Marshal(old) if err != nil { - return errors.Wrap(err, "unmarshalling properties") + panic(fmt.Sprintf("marshalling old: %v", err)) } if err := yaml.Unmarshal(contents, new); err != nil { - return errors.Wrap(err, "unmarshalling bazel artifact") + panic(fmt.Sprintf("unmarshalling new: %v", err)) } - return nil } // AbsolutePaths prepends each path in paths with workspace if the path isn't absolute diff --git a/pkg/skaffold/util/util_test.go b/pkg/skaffold/util/util_test.go index f2d5f7767cf..01fb40289d7 100644 --- a/pkg/skaffold/util/util_test.go +++ b/pkg/skaffold/util/util_test.go @@ -220,9 +220,35 @@ func TestCloneThroughJSON(t *testing.T) { } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - err := CloneThroughJSON(test.old, test.new) + CloneThroughJSON(test.old, test.new) + + t.CheckDeepEqual(test.expected, test.new) + }) + } +} + +func TestCloneThroughYAML(t *testing.T) { + tests := []struct { + description string + old interface{} + new interface{} + expected interface{} + }{ + { + description: "google cloud build", + old: map[string]string{ + "projectId": "unit-test", + }, + new: &latest.GoogleCloudBuild{}, + expected: &latest.GoogleCloudBuild{ + ProjectID: "unit-test", + }, + }, + } + for _, test := range tests { + testutil.Run(t, test.description, func(t *testutil.T) { + CloneThroughYAML(test.old, test.new) - t.CheckNoError(err) t.CheckDeepEqual(test.expected, test.new) }) } From 54678347438fe26fbe81e38c2c725e6a8312ddba Mon Sep 17 00:00:00 2001 From: David Gageot Date: Tue, 27 Aug 2019 16:30:11 +0200 Subject: [PATCH 34/69] =?UTF-8?q?[Caching]=20Artifact=E2=80=99s=20config?= =?UTF-8?q?=20is=20an=20input=20to=20digest=20calculation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #2694 Signed-off-by: David Gageot --- pkg/skaffold/build/cache/hash.go | 30 +++++++-- pkg/skaffold/build/cache/hash_test.go | 92 +++++++++++++++++++++++---- 2 files changed, 102 insertions(+), 20 deletions(-) diff --git a/pkg/skaffold/build/cache/hash.go b/pkg/skaffold/build/cache/hash.go index 2a29f1c43d4..b04f9cb88fa 100644 --- a/pkg/skaffold/build/cache/hash.go +++ b/pkg/skaffold/build/cache/hash.go @@ -30,37 +30,56 @@ import ( "github.com/pkg/errors" ) +// For testing var ( - // For testing - hashFunction = cacheHasher + hashFunction = cacheHasher + artifactConfigFunction = artifactConfig ) func getHashForArtifact(ctx context.Context, depLister DependencyLister, a *latest.Artifact) (string, error) { + var inputs []string + + // Append the artifact's configuration + config, err := artifactConfigFunction(a) + if err != nil { + return "", errors.Wrapf(err, "getting artifact's configuration for %s", a.ImageName) + } + inputs = append(inputs, config) + + // Append the digest of each input file deps, err := depLister.DependenciesForArtifact(ctx, a) if err != nil { return "", errors.Wrapf(err, "getting dependencies for %s", a.ImageName) } sort.Strings(deps) - var hashes []string for _, d := range deps { h, err := hashFunction(d) if err != nil { return "", errors.Wrapf(err, "getting hash for %s", d) } - hashes = append(hashes, h) + inputs = append(inputs, h) } // get a key for the hashes hasher := sha256.New() enc := json.NewEncoder(hasher) - if err := enc.Encode(hashes); err != nil { + if err := enc.Encode(inputs); err != nil { return "", err } return hex.EncodeToString(hasher.Sum(nil)), nil } +func artifactConfig(a *latest.Artifact) (string, error) { + buf, err := json.Marshal(a.ArtifactType) + if err != nil { + return "", errors.Wrapf(err, "marshalling the artifact's configuration for %s", a.ImageName) + } + + return string(buf), nil +} + // cacheHasher takes hashes the contents and name of a file func cacheHasher(p string) (string, error) { h := md5.New() @@ -70,7 +89,6 @@ func cacheHasher(p string) (string, error) { } h.Write([]byte(fi.Mode().String())) h.Write([]byte(fi.Name())) - // TODO: empty folder and empty files should not have the same hash if fi.Mode().IsRegular() { f, err := os.Open(p) if err != nil { diff --git a/pkg/skaffold/build/cache/hash_test.go b/pkg/skaffold/build/cache/hash_test.go index 3ce9f7532a8..247b1cfaf51 100644 --- a/pkg/skaffold/build/cache/hash_test.go +++ b/pkg/skaffold/build/cache/hash_test.go @@ -36,36 +36,100 @@ var mockCacheHasher = func(s string) (string, error) { return s, nil } +var fakeArtifactConfig = func(a *latest.Artifact) (string, error) { + if a.ArtifactType.DockerArtifact != nil { + return "docker/target=" + a.ArtifactType.DockerArtifact.Target, nil + } + return "other", nil +} + func TestGetHashForArtifact(t *testing.T) { tests := []struct { description string - dependencies [][]string + dependencies []string + artifact *latest.Artifact expected string }{ { - description: "check dependencies in different orders", - dependencies: [][]string{ - {"a", "b"}, - {"b", "a"}, + description: "hash for artifact", + dependencies: []string{"a", "b"}, + artifact: &latest.Artifact{}, + expected: "1caa15f7ce87536bddbac30a39768e8e3b212bf591f9b64926fa50c40b614c66", + }, + { + description: "dependencies in different orders", + dependencies: []string{"b", "a"}, + artifact: &latest.Artifact{}, + expected: "1caa15f7ce87536bddbac30a39768e8e3b212bf591f9b64926fa50c40b614c66", + }, + { + description: "no dependencies", + artifact: &latest.Artifact{}, + expected: "53ebd85adc9b03923a7dacfe6002879af526ef6067d441419d6e62fb9bf608ab", + }, + { + description: "docker target", + artifact: &latest.Artifact{ + ArtifactType: latest.ArtifactType{ + DockerArtifact: &latest.DockerArtifact{ + Target: "target", + }, + }, + }, + expected: "f947b5aad32734914aa2dea0ec95bceff257037e6c2a529007183c3f21547eae", + }, + { + description: "different docker target", + artifact: &latest.Artifact{ + ArtifactType: latest.ArtifactType{ + DockerArtifact: &latest.DockerArtifact{ + Target: "other", + }, + }, }, - expected: "eb394fd4559b1d9c383f4359667a508a615b82a74e1b160fce539f86ae0842e8", + expected: "09b366c764d0e39f942283cc081d5522b9dde52e725376661808054e3ed0177f", }, } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { t.Override(&hashFunction, mockCacheHasher) + t.Override(&artifactConfigFunction, fakeArtifactConfig) - for _, d := range test.dependencies { - depLister := &stubDependencyLister{dependencies: d} - actual, err := getHashForArtifact(context.Background(), depLister, nil) + depLister := &stubDependencyLister{dependencies: test.dependencies} + actual, err := getHashForArtifact(context.Background(), depLister, test.artifact) - t.CheckNoError(err) - t.CheckDeepEqual(test.expected, actual) - } + t.CheckNoError(err) + t.CheckDeepEqual(test.expected, actual) }) } } +func TestArtifactConfig(t *testing.T) { + testutil.Run(t, "", func(t *testutil.T) { + config1, err := artifactConfig(&latest.Artifact{ + ArtifactType: latest.ArtifactType{ + DockerArtifact: &latest.DockerArtifact{ + Target: "target", + }, + }, + }) + t.CheckNoError(err) + + config2, err := artifactConfig(&latest.Artifact{ + ArtifactType: latest.ArtifactType{ + DockerArtifact: &latest.DockerArtifact{ + Target: "other", + }, + }, + }) + t.CheckNoError(err) + + if config1 == config2 { + t.Errorf("configs should be different: [%s] [%s]", config1, config2) + } + }) +} + func TestCacheHasher(t *testing.T) { tests := []struct { description string @@ -114,7 +178,7 @@ func TestCacheHasher(t *testing.T) { path := originalFile depLister := &stubDependencyLister{dependencies: []string{tmpDir.Path(originalFile)}} - oldHash, err := getHashForArtifact(context.Background(), depLister, nil) + oldHash, err := getHashForArtifact(context.Background(), depLister, &latest.Artifact{}) t.CheckNoError(err) test.update(originalFile, tmpDir) @@ -123,7 +187,7 @@ func TestCacheHasher(t *testing.T) { } depLister = &stubDependencyLister{dependencies: []string{tmpDir.Path(path)}} - newHash, err := getHashForArtifact(context.Background(), depLister, nil) + newHash, err := getHashForArtifact(context.Background(), depLister, &latest.Artifact{}) t.CheckNoError(err) t.CheckDeepEqual(false, test.differentHash && oldHash == newHash) From 9cbc539f85ae87e0821f252cd0876abd5b3692d8 Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Tue, 27 Aug 2019 22:25:52 -0700 Subject: [PATCH 35/69] Bazel query should specify --output (#2712) --- pkg/skaffold/build/bazel/dependencies.go | 2 +- pkg/skaffold/build/bazel/dependencies_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/skaffold/build/bazel/dependencies.go b/pkg/skaffold/build/bazel/dependencies.go index 2a0c81317d3..4776f40f805 100644 --- a/pkg/skaffold/build/bazel/dependencies.go +++ b/pkg/skaffold/build/bazel/dependencies.go @@ -58,7 +58,7 @@ func GetDependencies(ctx context.Context, dir string, a *latest.BazelArtifact) ( return nil, errors.Wrapf(err, "unable to find absolute path for %s", dir) } - cmd := exec.CommandContext(ctx, "bazel", "query", query(a.BuildTarget), "--noimplicit_deps", "--order_output=no") + cmd := exec.CommandContext(ctx, "bazel", "query", query(a.BuildTarget), "--noimplicit_deps", "--order_output=no", "--output=label") cmd.Dir = dir stdout, err := util.RunCmdOut(cmd) if err != nil { diff --git a/pkg/skaffold/build/bazel/dependencies_test.go b/pkg/skaffold/build/bazel/dependencies_test.go index 79ad916f5f2..dc6b38dc074 100644 --- a/pkg/skaffold/build/bazel/dependencies_test.go +++ b/pkg/skaffold/build/bazel/dependencies_test.go @@ -47,7 +47,7 @@ func TestGetDependencies(t *testing.T) { "dep1": "", "dep2": "", }, - expectedQuery: "bazel query kind('source file', deps('target')) union buildfiles('target') --noimplicit_deps --order_output=no", + expectedQuery: "bazel query kind('source file', deps('target')) union buildfiles('target') --noimplicit_deps --order_output=no --output=label", output: "@ignored\n//:BUILD\n//external/ignored\n\n//:dep1\n//:dep2\n", expected: []string{"BUILD", "dep1", "dep2", "WORKSPACE"}, }, @@ -63,7 +63,7 @@ func TestGetDependencies(t *testing.T) { "sub/folder/dep2": "", "sub/folder/baz/dep3": "", }, - expectedQuery: "bazel query kind('source file', deps('target2')) union buildfiles('target2') --noimplicit_deps --order_output=no", + expectedQuery: "bazel query kind('source file', deps('target2')) union buildfiles('target2') --noimplicit_deps --order_output=no --output=label", output: "@ignored\n//:BUILD\n//sub/folder:BUILD\n//external/ignored\n\n//sub/folder:dep1\n//sub/folder:dep2\n//sub/folder/baz:dep3\n", expected: []string{filepath.Join("..", "..", "BUILD"), "BUILD", "dep1", "dep2", filepath.Join("baz", "dep3"), filepath.Join("..", "..", "WORKSPACE")}, }, From 8a55ddc346c9cfee82a66511d85cab0f0db08f7a Mon Sep 17 00:00:00 2001 From: Andreas Sommer Date: Wed, 28 Aug 2019 07:34:28 +0200 Subject: [PATCH 36/69] Document Docker buildArgs as templated field (#2696) * Ignore bin directory * Document Docker buildArgs as templated field --- .gitignore | 1 + docs/content/en/docs/how-tos/templating/_index.md | 1 + 2 files changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 92329b3b996..54c2de8a9e1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +bin/ out/ examples/bazel/bazel-* integration/examples/bazel/bazel-* diff --git a/docs/content/en/docs/how-tos/templating/_index.md b/docs/content/en/docs/how-tos/templating/_index.md index 49222afc0ed..619df444480 100755 --- a/docs/content/en/docs/how-tos/templating/_index.md +++ b/docs/content/en/docs/how-tos/templating/_index.md @@ -14,6 +14,7 @@ will be `gcr.io/k8s-skaffold/example:v1`. List of fields that support templating: +* `build.artifacts.[].docker.buildArgs` (see [builders](/docs/how-tos/builders/)) * `build.tagPolicy.envTemplate.template` (see [envTemplate tagger](/docs/how-tos/taggers/##envtemplate-using-values-of-environment-variables-as-tags)) * `deploy.helm.releases.setValueTemplates` (see [Deploying with helm](/docs/how-tos/deployers/#deploying-with-helm)) From 52babb39797d49376b977bf8ab16f7181afb1c2a Mon Sep 17 00:00:00 2001 From: Russell Wolf Date: Tue, 27 Aug 2019 22:35:02 -0700 Subject: [PATCH 37/69] Directs "Download" button to Quickstart (#2695) -Directs the "Download" button on the homepage of skaffold.dev to the quickstart in the documentation instead of having the user navigate to GitHub where they eventually discover a link that takes them to the quickstart -Updates the logo of the "Download" button from the GitHub logo to a more clear "Download" logo --- docs/content/en/_index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content/en/_index.html b/docs/content/en/_index.html index cf9b7970c7b..a5328792d60 100644 --- a/docs/content/en/_index.html +++ b/docs/content/en/_index.html @@ -9,8 +9,8 @@ }}"> Learn More - - Download + + Download
{{< blocks/link-down color="info" >}} From 7ae6f9bd8deea692c0805c929cb5848a257027c8 Mon Sep 17 00:00:00 2001 From: Tejal Desai Date: Tue, 27 Aug 2019 22:35:48 -0700 Subject: [PATCH 38/69] Add UPSTREAM_CLIENT_TYPE user agent environment varaible to kaniko pod (#2723) --- pkg/skaffold/build/cluster/sources/gcs.go | 3 ++- pkg/skaffold/build/cluster/sources/localdir.go | 3 ++- .../build/cluster/sources/localdir_test.go | 3 +++ pkg/skaffold/build/cluster/sources/sources.go | 9 ++++++++- pkg/skaffold/build/cluster/sources/sources_test.go | 14 +++++++++++++- 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/pkg/skaffold/build/cluster/sources/gcs.go b/pkg/skaffold/build/cluster/sources/gcs.go index 58c2b8dcab0..53f3aec08fe 100644 --- a/pkg/skaffold/build/cluster/sources/gcs.go +++ b/pkg/skaffold/build/cluster/sources/gcs.go @@ -26,6 +26,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/gcp" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/sources" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/version" "github.com/pkg/errors" v1 "k8s.io/api/core/v1" ) @@ -61,7 +62,7 @@ func (g *GCSBucket) Setup(ctx context.Context, out io.Writer, artifact *latest.A // Pod returns the pod template for this builder func (g *GCSBucket) Pod(args []string) *v1.Pod { - return podTemplate(g.clusterDetails, g.artifact, args) + return podTemplate(g.clusterDetails, g.artifact, args, version.Get().Version) } // ModifyPod does nothing here, since we just need to let kaniko run to completion diff --git a/pkg/skaffold/build/cluster/sources/localdir.go b/pkg/skaffold/build/cluster/sources/localdir.go index 5966a81a1c5..16f547ccdde 100644 --- a/pkg/skaffold/build/cluster/sources/localdir.go +++ b/pkg/skaffold/build/cluster/sources/localdir.go @@ -23,6 +23,7 @@ import ( "os" "path/filepath" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/version" "github.com/pkg/errors" v1 "k8s.io/api/core/v1" @@ -86,7 +87,7 @@ func (g *LocalDir) Pod(args []string) *v1.Pod { Resources: resourceRequirements(g.clusterDetails.Resources), } - p := podTemplate(g.clusterDetails, g.artifact, args) + p := podTemplate(g.clusterDetails, g.artifact, args, version.Get().Version) p.Spec.InitContainers = []v1.Container{ic} p.Spec.Containers[0].VolumeMounts = append(p.Spec.Containers[0].VolumeMounts, vm) p.Spec.Volumes = append(p.Spec.Volumes, v) diff --git a/pkg/skaffold/build/cluster/sources/localdir_test.go b/pkg/skaffold/build/cluster/sources/localdir_test.go index 41db72e10aa..2daeb94be0d 100644 --- a/pkg/skaffold/build/cluster/sources/localdir_test.go +++ b/pkg/skaffold/build/cluster/sources/localdir_test.go @@ -30,6 +30,9 @@ func TestPod(t *testing.T) { env := []v1.EnvVar{{ Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: "/secret/kaniko-secret", + }, { + Name: "UPSTREAM_CLIENT_TYPE", + Value: "UpstreamClient(skaffold-)", }} reqs := &latest.ResourceRequirements{ Requests: &latest.ResourceRequirement{ diff --git a/pkg/skaffold/build/cluster/sources/sources.go b/pkg/skaffold/build/cluster/sources/sources.go index 19cddd61045..06b816eefaf 100644 --- a/pkg/skaffold/build/cluster/sources/sources.go +++ b/pkg/skaffold/build/cluster/sources/sources.go @@ -18,6 +18,7 @@ package sources import ( "context" + "fmt" "io" v1 "k8s.io/api/core/v1" @@ -53,10 +54,16 @@ func Retrieve(cli *kubectl.CLI, clusterDetails *latest.ClusterDetails, artifact } } -func podTemplate(clusterDetails *latest.ClusterDetails, artifact *latest.KanikoArtifact, args []string) *v1.Pod { +func podTemplate(clusterDetails *latest.ClusterDetails, artifact *latest.KanikoArtifact, args []string, version string) *v1.Pod { + userAgent := fmt.Sprintf("UpstreamClient(skaffold-%s)", version) + env := []v1.EnvVar{{ Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: "/secret/kaniko-secret", + }, { + // This should be same https://github.com/GoogleContainerTools/kaniko/blob/77cfb912f3483c204bfd09e1ada44fd200b15a78/pkg/executor/push.go#L49 + Name: "UPSTREAM_CLIENT_TYPE", + Value: userAgent, }} env = setProxy(clusterDetails, env) diff --git a/pkg/skaffold/build/cluster/sources/sources_test.go b/pkg/skaffold/build/cluster/sources/sources_test.go index 737b1194dfd..bb1093a004c 100644 --- a/pkg/skaffold/build/cluster/sources/sources_test.go +++ b/pkg/skaffold/build/cluster/sources/sources_test.go @@ -55,6 +55,9 @@ func TestPodTemplate(t *testing.T) { Env: []v1.EnvVar{{ Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: "/secret/kaniko-secret", + }, { + Name: "UPSTREAM_CLIENT_TYPE", + Value: "UpstreamClient(skaffold-test)", }}, VolumeMounts: []v1.VolumeMount{{ Name: "kaniko-secret", @@ -99,6 +102,9 @@ func TestPodTemplate(t *testing.T) { Env: []v1.EnvVar{{ Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: "/secret/kaniko-secret", + }, { + Name: "UPSTREAM_CLIENT_TYPE", + Value: "UpstreamClient(skaffold-test)", }}, VolumeMounts: []v1.VolumeMount{ { @@ -163,6 +169,9 @@ func TestPodTemplate(t *testing.T) { Env: []v1.EnvVar{{ Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: "/secret/kaniko-secret", + }, { + Name: "UPSTREAM_CLIENT_TYPE", + Value: "UpstreamClient(skaffold-test)", }}, VolumeMounts: []v1.VolumeMount{{ Name: "kaniko-secret", @@ -208,6 +217,9 @@ func TestPodTemplate(t *testing.T) { Env: []v1.EnvVar{{ Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: "/secret/kaniko-secret", + }, { + Name: "UPSTREAM_CLIENT_TYPE", + Value: "UpstreamClient(skaffold-test)", }}, VolumeMounts: []v1.VolumeMount{{ Name: "kaniko-secret", @@ -244,7 +256,7 @@ func TestPodTemplate(t *testing.T) { for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { - actual := podTemplate(test.initial, test.artifact, test.args) + actual := podTemplate(test.initial, test.artifact, test.args, "test") t.CheckDeepEqual(test.expected, actual, opt) }) From c5aecde6e91f41c329b30bcd5a44a4470548b397 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Wed, 28 Aug 2019 10:21:39 +0200 Subject: [PATCH 39/69] Simplify test script Signed-off-by: David Gageot --- Makefile | 1 + hack/test.sh | 8 +------- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 626897cb4c4..1db511c1da7 100644 --- a/Makefile +++ b/Makefile @@ -100,6 +100,7 @@ cross: $(foreach platform, $(SUPPORTED_PLATFORMS), $(BUILD_DIR)/$(PROJECT)-$(pla .PHONY: test test: $(BUILD_DIR) @ ./hack/test.sh + @ ./hack/checks.sh .PHONY: checks checks: $(BUILD_DIR) diff --git a/hack/test.sh b/hack/test.sh index ecfebff2091..dd3344e5993 100755 --- a/hack/test.sh +++ b/hack/test.sh @@ -17,15 +17,9 @@ set -e RED='\033[0;31m' -GREEN='\033[0;32m' RESET='\033[0m' echo "Running go tests..." go test -count=1 -race -cover -short -timeout=60s -coverprofile=out/coverage.txt -coverpkg="./pkg/...,./cmd/..." ./... | awk -v FAIL="${RED}FAIL${RESET}" '! /no test files/ { gsub("FAIL", FAIL, $0); print $0 }' -GO_TEST_EXIT_CODE=${PIPESTATUS[0]} -if [[ $GO_TEST_EXIT_CODE -ne 0 ]]; then - exit $GO_TEST_EXIT_CODE -fi - -hack/checks.sh +exit ${PIPESTATUS[0]} From 284a29ed6664a591aa9f93055816f19d31238ca2 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Wed, 28 Aug 2019 10:22:31 +0200 Subject: [PATCH 40/69] =?UTF-8?q?Simplify=20CI=20script=20on=20OSX=20and?= =?UTF-8?q?=20don=E2=80=99t=20upload=20coverage=20report?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: David Gageot --- .travis.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index e42e73b8fa8..ae31e7e5ad6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,14 +26,9 @@ jobs: - bash <(curl -s https://codecov.io/bash) - os: osx name: "OSX unit" - env: - - GO111MODULE=on - - GOFLAGS="-mod=vendor" script: - - go build -o out/skaffold cmd/skaffold/skaffold.go - - go test -short -timeout 60s ./... - after_success: - - bash <(curl -s https://codecov.io/bash) + - make + - make quicktest - os: windows name: "Windows unit" env: From 0762ac9103e4fb631998d7c6b6190368008a33ae Mon Sep 17 00:00:00 2001 From: David Gageot Date: Wed, 28 Aug 2019 10:31:08 +0200 Subject: [PATCH 41/69] Restore race detection and coverage upload Signed-off-by: David Gageot --- .travis.yml | 4 +--- Makefile | 6 ++++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index ae31e7e5ad6..e6bf9810de8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,9 +21,7 @@ jobs: name: "Linux unit" script: - make - - make quicktest - after_success: - - bash <(curl -s https://codecov.io/bash) + - make coverage - os: osx name: "OSX unit" script: diff --git a/Makefile b/Makefile index 1db511c1da7..434d6ca2e31 100644 --- a/Makefile +++ b/Makefile @@ -102,6 +102,12 @@ test: $(BUILD_DIR) @ ./hack/test.sh @ ./hack/checks.sh +.PHONY: coverage +coverage: $(BUILD_DIR) + @ ./hack/test.sh + @ curl -s https://codecov.io/bash > $(BUILD_DIR)/upload_coverage + @ bash $(BUILD_DIR)/upload_coverage + .PHONY: checks checks: $(BUILD_DIR) @ ./hack/checks.sh From 4ab8f394aa2b30afb3cc36c4c9e001f276610dcb Mon Sep 17 00:00:00 2001 From: David Gageot Date: Wed, 28 Aug 2019 10:36:28 +0200 Subject: [PATCH 42/69] Restore colors and simplify script Signed-off-by: David Gageot --- hack/checks.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hack/checks.sh b/hack/checks.sh index 22819fcc483..ca2bc97ccd1 100755 --- a/hack/checks.sh +++ b/hack/checks.sh @@ -14,6 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +RED='\033[0;31m' +GREEN='\033[0;32m' +RESET='\033[0m' + echo "Running validation scripts..." scripts=( "hack/boilerplate.sh" @@ -26,10 +30,10 @@ scripts=( fail=0 for s in "${scripts[@]}"; do echo "RUN ${s}" - set +e + ./$s result=$? - set -e + if [[ $result -eq 0 ]]; then echo -e "${GREEN}PASSED${RESET} ${s}" else From bbe58e91b975e2fc8f4e8f529583220b6c4607d3 Mon Sep 17 00:00:00 2001 From: Taylor Barrella Date: Wed, 28 Aug 2019 01:40:11 -0700 Subject: [PATCH 43/69] Don't panic when dockerConfig isn't provided (#2735) Prevously, the custom in-cluster builder would break with default configuration --- pkg/skaffold/build/cluster/cluster.go | 7 +++++-- pkg/skaffold/build/cluster/cluster_test.go | 21 ++++++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/pkg/skaffold/build/cluster/cluster.go b/pkg/skaffold/build/cluster/cluster.go index 1389cec98aa..7898bdc5f48 100644 --- a/pkg/skaffold/build/cluster/cluster.go +++ b/pkg/skaffold/build/cluster/cluster.go @@ -72,13 +72,16 @@ func (b *Builder) buildArtifactWithCustomBuilder(ctx context.Context, out io.Wri } func (b *Builder) retrieveExtraEnv() []string { - return []string{ + env := []string{ fmt.Sprintf("%s=%s", constants.KubeContext, b.kubeContext), fmt.Sprintf("%s=%s", constants.Namespace, b.ClusterDetails.Namespace), fmt.Sprintf("%s=%s", constants.PullSecretName, b.ClusterDetails.PullSecretName), - fmt.Sprintf("%s=%s", constants.DockerConfigSecretName, b.ClusterDetails.DockerConfig.SecretName), fmt.Sprintf("%s=%s", constants.Timeout, b.ClusterDetails.Timeout), } + if b.ClusterDetails.DockerConfig != nil { + env = append(env, fmt.Sprintf("%s=%s", constants.DockerConfigSecretName, b.ClusterDetails.DockerConfig.SecretName)) + } + return env } func (b *Builder) buildArtifactWithKaniko(ctx context.Context, out io.Writer, artifact *latest.Artifact, tag string) (string, error) { diff --git a/pkg/skaffold/build/cluster/cluster_test.go b/pkg/skaffold/build/cluster/cluster_test.go index 390e49d6b87..c34e0c76ff9 100644 --- a/pkg/skaffold/build/cluster/cluster_test.go +++ b/pkg/skaffold/build/cluster/cluster_test.go @@ -49,6 +49,25 @@ func TestRetrieveEnv(t *testing.T) { testutil.CheckError(t, false, err) actual := builder.retrieveExtraEnv() - expected := []string{"KUBE_CONTEXT=kubecontext", "NAMESPACE=namespace", "PULL_SECRET_NAME=pullSecret", "DOCKER_CONFIG_SECRET_NAME=dockerconfig", "TIMEOUT=2m"} + expected := []string{"KUBE_CONTEXT=kubecontext", "NAMESPACE=namespace", "PULL_SECRET_NAME=pullSecret", "TIMEOUT=2m", "DOCKER_CONFIG_SECRET_NAME=dockerconfig"} + testutil.CheckDeepEqual(t, expected, actual) +} + +func TestRetrieveEnvMinimal(t *testing.T) { + builder, err := NewBuilder(&runcontext.RunContext{ + Cfg: latest.Pipeline{ + Build: latest.BuildConfig{ + BuildType: latest.BuildType{ + Cluster: &latest.ClusterDetails{ + Timeout: "20m", + }, + }, + }, + }, + }) + testutil.CheckError(t, false, err) + + actual := builder.retrieveExtraEnv() + expected := []string{"KUBE_CONTEXT=", "NAMESPACE=", "PULL_SECRET_NAME=", "TIMEOUT=20m"} testutil.CheckDeepEqual(t, expected, actual) } From 371e88c5a38f40dd454bd349d76367060453f12b Mon Sep 17 00:00:00 2001 From: David Gageot Date: Tue, 27 Aug 2019 08:54:11 +0200 Subject: [PATCH 44/69] Add missing integration tests for skaffold diagnose Signed-off-by: David Gageot --- integration/diagnose_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration/diagnose_test.go b/integration/diagnose_test.go index 0612d2f59db..3496b7473ab 100644 --- a/integration/diagnose_test.go +++ b/integration/diagnose_test.go @@ -33,17 +33,17 @@ func TestDiagnose(t *testing.T) { tests := []struct { name string dir string - args []string }{ {name: "kaniko builder", dir: "examples/kaniko"}, {name: "docker builder", dir: "examples/nodejs"}, {name: "jib maven builder", dir: "testdata/jib"}, + {name: "jib gradle builder", dir: "testdata/jib-gradle"}, {name: "bazel builder", dir: "examples/bazel"}, - // todo add test cases for "jib gradle builder" and "custom builder" + {name: "custom builder", dir: "testdata/custom"}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - skaffold.Diagnose(test.args...).InDir(test.dir).RunOrFailOutput(t) + skaffold.Diagnose().InDir(test.dir).RunOrFailOutput(t) }) } } From a36142a017bea4f6d381f7cd38dfe29c9f63a364 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Tue, 27 Aug 2019 09:09:24 +0200 Subject: [PATCH 45/69] [Custom builder] Default to empty dependencies Fix #2683 Signed-off-by: David Gageot --- pkg/skaffold/schema/defaults/defaults.go | 11 ++++++++++- pkg/skaffold/schema/defaults/defaults_test.go | 10 ++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/pkg/skaffold/schema/defaults/defaults.go b/pkg/skaffold/schema/defaults/defaults.go index 68601d62ae5..201f5b783a9 100644 --- a/pkg/skaffold/schema/defaults/defaults.go +++ b/pkg/skaffold/schema/defaults/defaults.go @@ -19,7 +19,7 @@ package defaults import ( "fmt" - "github.com/mitchellh/go-homedir" + homedir "github.com/mitchellh/go-homedir" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -68,6 +68,7 @@ func Set(c *latest.SkaffoldConfig) error { setDefaultWorkspace(a) defaultToDockerArtifact(a) setDefaultDockerfile(a) + setDefaultCustomDependencies(a) } for _, pf := range c.PortForward { @@ -154,6 +155,14 @@ func setDefaultDockerfile(a *latest.Artifact) { } } +func setDefaultCustomDependencies(a *latest.Artifact) { + if a.CustomArtifact != nil { + if a.CustomArtifact.Dependencies == nil { + a.CustomArtifact.Dependencies = &latest.CustomDependencies{} + } + } +} + // SetDefaultDockerArtifact sets defaults on docker artifacts func SetDefaultDockerArtifact(a *latest.DockerArtifact) { a.DockerfilePath = valueOrDefault(a.DockerfilePath, constants.DefaultDockerfilePath) diff --git a/pkg/skaffold/schema/defaults/defaults_test.go b/pkg/skaffold/schema/defaults/defaults_test.go index 197248bb6d8..09d72099cbb 100644 --- a/pkg/skaffold/schema/defaults/defaults_test.go +++ b/pkg/skaffold/schema/defaults/defaults_test.go @@ -42,6 +42,12 @@ func TestSetDefaults(t *testing.T) { }, }, }, + { + ImageName: "third", + ArtifactType: latest.ArtifactType{ + CustomArtifact: &latest.CustomArtifact{}, + }, + }, }, }, }, @@ -58,6 +64,10 @@ func TestSetDefaults(t *testing.T) { testutil.CheckDeepEqual(t, "second", cfg.Build.Artifacts[1].ImageName) testutil.CheckDeepEqual(t, "folder", cfg.Build.Artifacts[1].Workspace) testutil.CheckDeepEqual(t, "Dockerfile.second", cfg.Build.Artifacts[1].DockerArtifact.DockerfilePath) + + testutil.CheckDeepEqual(t, "third", cfg.Build.Artifacts[2].ImageName) + testutil.CheckDeepEqual(t, []string(nil), cfg.Build.Artifacts[2].CustomArtifact.Dependencies.Paths) + testutil.CheckDeepEqual(t, []string(nil), cfg.Build.Artifacts[2].CustomArtifact.Dependencies.Ignore) } func TestSetDefaultsOnCluster(t *testing.T) { From 0c3e558134a3a07440dbb10eb2039c9ad6265d1e Mon Sep 17 00:00:00 2001 From: David Gageot Date: Tue, 27 Aug 2019 11:33:04 +0200 Subject: [PATCH 46/69] We must handle every profile field type This would have caught #1688 Signed-off-by: David Gageot --- pkg/skaffold/schema/profiles.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/skaffold/schema/profiles.go b/pkg/skaffold/schema/profiles.go index d8e7e302645..55c4f171aa7 100644 --- a/pkg/skaffold/schema/profiles.go +++ b/pkg/skaffold/schema/profiles.go @@ -292,7 +292,7 @@ func overlayProfileField(fieldName string, config interface{}, profile interface } return v.Interface() default: - logrus.Warnf("Type mismatch in profile overlay for field '%s' with type %s; falling back to original config values", fieldName, v.Kind()) + logrus.Fatalf("Type mismatch in profile overlay for field '%s' with type %s; falling back to original config values", fieldName, v.Kind()) return config } } From 4866dfc0faf648f4626f022e6480067cc65a2c41 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Wed, 28 Aug 2019 13:36:35 +0200 Subject: [PATCH 47/69] Show the duration of the deploy phase Fix #2738 Signed-off-by: David Gageot --- pkg/skaffold/runner/timings.go | 4 +- pkg/skaffold/runner/timings_test.go | 237 ++++++++++++++++++++++++++++ testutil/util.go | 8 + 3 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 pkg/skaffold/runner/timings_test.go diff --git a/pkg/skaffold/runner/timings.go b/pkg/skaffold/runner/timings.go index 795fb38efed..c6f69bc44fa 100644 --- a/pkg/skaffold/runner/timings.go +++ b/pkg/skaffold/runner/timings.go @@ -88,8 +88,10 @@ func (w withTimings) Deploy(ctx context.Context, out io.Writer, builds []build.A dr := w.Deployer.Deploy(ctx, out, builds, labellers) if err := dr.GetError(); err != nil { - color.Default.Fprintln(out, "Deploy complete in", time.Since(start)) + return dr } + + color.Default.Fprintln(out, "Deploy complete in", time.Since(start)) return dr } diff --git a/pkg/skaffold/runner/timings_test.go b/pkg/skaffold/runner/timings_test.go new file mode 100644 index 00000000000..c71dad06a7f --- /dev/null +++ b/pkg/skaffold/runner/timings_test.go @@ -0,0 +1,237 @@ +/* +Copyright 2019 The Skaffold 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 runner + +import ( + "bytes" + "context" + "io" + "testing" + + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/tag" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/deploy" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/test" + "github.com/GoogleContainerTools/skaffold/testutil" + "github.com/pkg/errors" +) + +type mockBuilder struct { + build.Builder + err bool +} + +func (m *mockBuilder) Build(context.Context, io.Writer, tag.ImageTags, []*latest.Artifact) ([]build.Artifact, error) { + if m.err { + return nil, errors.New("Unable to build") + } + return nil, nil +} + +func (m *mockBuilder) Prune(context.Context, io.Writer) error { + if m.err { + return errors.New("Unable to prune") + } + return nil +} + +type mockTester struct { + test.Tester + err bool +} + +func (m *mockTester) Test(context.Context, io.Writer, []build.Artifact) error { + if m.err { + return errors.New("Unable to test") + } + return nil +} + +type mockDeployer struct { + deploy.Deployer + err bool +} + +func (m *mockDeployer) Deploy(context.Context, io.Writer, []build.Artifact, []deploy.Labeller) *deploy.Result { + if m.err { + return deploy.NewDeployErrorResult(errors.New("Unable to deploy")) + } + return deploy.NewDeploySuccessResult(nil) +} + +func (m *mockDeployer) Cleanup(context.Context, io.Writer) error { + if m.err { + return errors.New("Unable to cleanup") + } + return nil +} + +func TestTimingsBuild(t *testing.T) { + tests := []struct { + description string + shouldOutput string + shouldErr bool + }{ + { + description: "build success", + shouldOutput: "(?m)^Starting build...\nBuild complete in .+$", + shouldErr: false, + }, + { + description: "build failure", + shouldOutput: "^Starting build...\n$", + shouldErr: true, + }, + } + for _, test := range tests { + testutil.Run(t, test.description, func(t *testutil.T) { + b := &mockBuilder{err: test.shouldErr} + builder, _, _ := WithTimings(b, nil, nil, false) + + var out bytes.Buffer + _, err := builder.Build(context.Background(), &out, nil, nil) + + t.CheckError(test.shouldErr, err) + t.CheckMatches(test.shouldOutput, out.String()) + }) + } +} + +func TestTimingsPrune(t *testing.T) { + tests := []struct { + description string + shouldOutput string + shouldErr bool + }{ + { + description: "test success", + shouldOutput: "(?m)^Pruning images...\nImage prune complete in .+$", + shouldErr: false, + }, + { + description: "test failure", + shouldOutput: "^Pruning images...\n$", + shouldErr: true, + }, + } + for _, test := range tests { + testutil.Run(t, test.description, func(t *testutil.T) { + b := &mockBuilder{err: test.shouldErr} + builder, _, _ := WithTimings(b, nil, nil, false) + + var out bytes.Buffer + err := builder.Prune(context.Background(), &out) + + t.CheckError(test.shouldErr, err) + t.CheckMatches(test.shouldOutput, out.String()) + }) + } +} + +func TestTimingsTest(t *testing.T) { + tests := []struct { + description string + shouldOutput string + shouldErr bool + }{ + { + description: "test success", + shouldOutput: "(?m)^Starting test...\nTest complete in .+$", + shouldErr: false, + }, + { + description: "test failure", + shouldOutput: "^Starting test...\n$", + shouldErr: true, + }, + } + for _, test := range tests { + testutil.Run(t, test.description, func(t *testutil.T) { + tt := &mockTester{err: test.shouldErr} + _, tester, _ := WithTimings(nil, tt, nil, false) + + var out bytes.Buffer + err := tester.Test(context.Background(), &out, nil) + + t.CheckError(test.shouldErr, err) + t.CheckMatches(test.shouldOutput, out.String()) + }) + } +} + +func TestTimingsDeploy(t *testing.T) { + tests := []struct { + description string + shouldOutput string + shouldErr bool + }{ + { + description: "prune success", + shouldOutput: "(?m)^Starting deploy...\nDeploy complete in .+$", + shouldErr: false, + }, + { + description: "prune failure", + shouldOutput: "^Starting deploy...\n$", + shouldErr: true, + }, + } + for _, test := range tests { + testutil.Run(t, test.description, func(t *testutil.T) { + d := &mockDeployer{err: test.shouldErr} + _, _, deployer := WithTimings(nil, nil, d, false) + + var out bytes.Buffer + res := deployer.Deploy(context.Background(), &out, nil, nil) + + t.CheckError(test.shouldErr, res.GetError()) + t.CheckMatches(test.shouldOutput, out.String()) + }) + } +} + +func TestTimingsCleanup(t *testing.T) { + tests := []struct { + description string + shouldOutput string + shouldErr bool + }{ + { + description: "cleanup success", + shouldOutput: "(?m)^Cleaning up...\nCleanup complete in .+$", + shouldErr: false, + }, + { + description: "cleanup failure", + shouldOutput: "^Cleaning up...\n$", + shouldErr: true, + }, + } + for _, test := range tests { + testutil.Run(t, test.description, func(t *testutil.T) { + d := &mockDeployer{err: test.shouldErr} + _, _, deployer := WithTimings(nil, nil, d, false) + + var out bytes.Buffer + err := deployer.Cleanup(context.Background(), &out) + + t.CheckError(test.shouldErr, err) + t.CheckMatches(test.shouldOutput, out.String()) + }) + } +} diff --git a/testutil/util.go b/testutil/util.go index 418df07c89e..2017d10e409 100644 --- a/testutil/util.go +++ b/testutil/util.go @@ -22,6 +22,7 @@ import ( "net/http" "net/http/httptest" "reflect" + "regexp" "strings" "testing" @@ -60,6 +61,13 @@ func (t *T) Override(dest, tmp interface{}) { t.teardownActions = append(t.teardownActions, teardown) } +func (t *T) CheckMatches(pattern, actual string) { + t.T.Helper() + if matches, _ := regexp.MatchString(pattern, actual); !matches { + t.Errorf("expected output %s to match: %s", actual, pattern) + } +} + func (t *T) CheckContains(expected, actual string) { CheckContains(t.T, expected, actual) } From 17dee6b99092488d92ecf854a95da7061ac8a62f Mon Sep 17 00:00:00 2001 From: David Gageot Date: Wed, 28 Aug 2019 20:23:49 +0200 Subject: [PATCH 48/69] Print the output of failed integration tests (#2725) Signed-off-by: David Gageot --- integration/deploy_test.go | 4 +--- integration/dev_test.go | 2 +- integration/diagnose_test.go | 2 +- integration/helm_test.go | 2 +- integration/port_forward_test.go | 2 +- integration/run_test.go | 2 +- integration/skaffold/helper.go | 5 +---- 7 files changed, 7 insertions(+), 12 deletions(-) diff --git a/integration/deploy_test.go b/integration/deploy_test.go index 085421e68a4..f6af05de9c7 100644 --- a/integration/deploy_test.go +++ b/integration/deploy_test.go @@ -128,7 +128,5 @@ func TestDeployWithInCorrectConfigWithNoStatusCheck(t *testing.T) { ns, _, deleteNs := SetupNamespace(t) defer deleteNs() - skaffold.Deploy().InDir("testdata/unstable-deployment").InNs(ns.Name).RunOrFailOutput(t) - - skaffold.Delete().InDir("testdata/unstable-deployment").InNs(ns.Name).RunOrFail(t) + skaffold.Deploy().InDir("testdata/unstable-deployment").InNs(ns.Name).RunOrFail(t) } diff --git a/integration/dev_test.go b/integration/dev_test.go index bc6b5dbc49e..0e717844a9b 100644 --- a/integration/dev_test.go +++ b/integration/dev_test.go @@ -389,7 +389,7 @@ func TestDev_WithKubecontextOverride(t *testing.T) { env := []string{fmt.Sprintf("KUBECONFIG=%s", kubeconfig)} // n.b. for the sake of this test the namespace must not be given explicitly - skaffold.Run("--kube-context", kubecontext).InDir(dir).WithEnv(env).RunOrFailOutput(t.T) + skaffold.Run("--kube-context", kubecontext).InDir(dir).WithEnv(env).RunOrFail(t.T) client.WaitForPodsReady(pods...) diff --git a/integration/diagnose_test.go b/integration/diagnose_test.go index 3496b7473ab..7d3740a745c 100644 --- a/integration/diagnose_test.go +++ b/integration/diagnose_test.go @@ -43,7 +43,7 @@ func TestDiagnose(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - skaffold.Diagnose().InDir(test.dir).RunOrFailOutput(t) + skaffold.Diagnose().InDir(test.dir).RunOrFail(t) }) } } diff --git a/integration/helm_test.go b/integration/helm_test.go index 7e41882b2af..658fd065c5f 100644 --- a/integration/helm_test.go +++ b/integration/helm_test.go @@ -50,7 +50,7 @@ func TestHelmDeploy(t *testing.T) { runArgs := []string{"--images", "gcr.io/k8s-skaffold/skaffold-helm"} - skaffold.Deploy(runArgs...).InDir(helmDir).InNs(ns.Name).WithEnv(env).RunOrFailOutput(t) + skaffold.Deploy(runArgs...).InDir(helmDir).InNs(ns.Name).WithEnv(env).RunOrFail(t) client.WaitForDeploymentsToStabilize(depName) diff --git a/integration/port_forward_test.go b/integration/port_forward_test.go index 098de507140..1d0d04fbee6 100644 --- a/integration/port_forward_test.go +++ b/integration/port_forward_test.go @@ -45,7 +45,7 @@ func TestPortForward(t *testing.T) { defer deleteNs() dir := "examples/microservices" - skaffold.Run().InDir(dir).InNs(ns.Name).RunOrFailOutput(t) + skaffold.Run().InDir(dir).InNs(ns.Name).RunOrFail(t) cfg, err := kubectx.CurrentConfig() if err != nil { diff --git a/integration/run_test.go b/integration/run_test.go index 685a27875c2..d2abd641ed6 100644 --- a/integration/run_test.go +++ b/integration/run_test.go @@ -137,7 +137,7 @@ func TestRun(t *testing.T) { ns, client, deleteNs := SetupNamespace(t) defer deleteNs() - skaffold.Run(test.args...).WithConfig(test.filename).InDir(test.dir).InNs(ns.Name).WithEnv(test.env).RunOrFailOutput(t) + skaffold.Run(test.args...).WithConfig(test.filename).InDir(test.dir).InNs(ns.Name).WithEnv(test.env).RunOrFail(t) client.WaitForPodsReady(test.pods...) client.WaitForDeploymentsToStabilize(test.deployments...) diff --git a/integration/skaffold/helper.go b/integration/skaffold/helper.go index fa2eaf778f2..6dbe9b9d8cd 100644 --- a/integration/skaffold/helper.go +++ b/integration/skaffold/helper.go @@ -154,10 +154,7 @@ func (b *RunBuilder) RunBackground(t *testing.T) context.CancelFunc { // RunOrFail runs the skaffold command and fails the test // if the command returns an error. func (b *RunBuilder) RunOrFail(t *testing.T) { - t.Helper() - if err := b.Run(t); err != nil { - t.Fatal(err) - } + b.RunOrFailOutput(t) } // Run runs the skaffold command. From 7f3ae85e3c60d923e5cf5cb53dd6a76ae00db7bf Mon Sep 17 00:00:00 2001 From: David Gageot Date: Wed, 28 Aug 2019 11:36:06 +0200 Subject: [PATCH 49/69] Pass extra env to the Docker CLI Fix #1749 Signed-off-by: David Gageot --- pkg/skaffold/build/local/docker.go | 3 +- pkg/skaffold/build/local/docker_test.go | 89 +++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 pkg/skaffold/build/local/docker_test.go diff --git a/pkg/skaffold/build/local/docker.go b/pkg/skaffold/build/local/docker.go index ef35c5218bb..20fe508deb5 100644 --- a/pkg/skaffold/build/local/docker.go +++ b/pkg/skaffold/build/local/docker.go @@ -73,8 +73,9 @@ func (b *Builder) dockerCLIBuild(ctx context.Context, out io.Writer, workspace s } cmd := exec.CommandContext(ctx, "docker", args...) + cmd.Env = append(util.OSEnviron(), b.retrieveExtraEnv()...) if b.cfg.UseBuildkit { - cmd.Env = append(util.OSEnviron(), "DOCKER_BUILDKIT=1") + cmd.Env = append(cmd.Env, "DOCKER_BUILDKIT=1") } cmd.Stdout = out cmd.Stderr = out diff --git a/pkg/skaffold/build/local/docker_test.go b/pkg/skaffold/build/local/docker_test.go new file mode 100644 index 00000000000..815e1961ace --- /dev/null +++ b/pkg/skaffold/build/local/docker_test.go @@ -0,0 +1,89 @@ +/* +Copyright 2019 The Skaffold 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 local + +import ( + "context" + "io/ioutil" + "path/filepath" + "testing" + + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner/runcontext" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" + "github.com/GoogleContainerTools/skaffold/testutil" +) + +func TestDockerCLIBuild(t *testing.T) { + tests := []struct { + description string + localBuild latest.LocalBuild + extraEnv []string + expectedEnv []string + }{ + { + description: "docker build", + localBuild: latest.LocalBuild{}, + expectedEnv: []string{"KEY=VALUE"}, + }, + { + description: "extra env", + localBuild: latest.LocalBuild{}, + extraEnv: []string{"OTHER=VALUE"}, + expectedEnv: []string{"KEY=VALUE", "OTHER=VALUE"}, + }, + { + description: "buildkit", + localBuild: latest.LocalBuild{UseBuildkit: true}, + expectedEnv: []string{"KEY=VALUE", "DOCKER_BUILDKIT=1"}, + }, + { + description: "buildkit and extra env", + localBuild: latest.LocalBuild{UseBuildkit: true}, + extraEnv: []string{"OTHER=VALUE"}, + expectedEnv: []string{"KEY=VALUE", "OTHER=VALUE", "DOCKER_BUILDKIT=1"}, + }, + } + + for _, test := range tests { + testutil.Run(t, test.description, func(t *testutil.T) { + t.NewTempDir().Chdir() + dockerfilePath, _ := filepath.Abs("Dockerfile") + t.Override(&util.DefaultExecCommand, t.NewFakeCmd().WithRunEnv("docker build . --file "+dockerfilePath+" -t tag --force-rm", test.expectedEnv)) + t.Override(&util.OSEnviron, func() []string { return []string{"KEY=VALUE"} }) + t.Override(&docker.NewAPIClient, func(*runcontext.RunContext) (docker.LocalDaemon, error) { + return docker.NewLocalDaemon(&testutil.FakeAPIClient{}, test.extraEnv, false, nil), nil + }) + + builder, err := NewBuilder(stubRunContext(test.localBuild)) + t.CheckNoError(err) + + artifact := &latest.Artifact{ + Workspace: ".", + ArtifactType: latest.ArtifactType{ + DockerArtifact: &latest.DockerArtifact{ + DockerfilePath: "Dockerfile", + }, + }, + } + + _, err = builder.buildDocker(context.Background(), ioutil.Discard, artifact, "tag") + t.CheckNoError(err) + }) + } +} From 897f34ff7315336046ec26113b52ab7d51a46de1 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Wed, 28 Aug 2019 17:10:50 +0200 Subject: [PATCH 50/69] Add a test with collisions Signed-off-by: David Gageot --- pkg/skaffold/build/local/docker_test.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/skaffold/build/local/docker_test.go b/pkg/skaffold/build/local/docker_test.go index 815e1961ace..ee17db6b116 100644 --- a/pkg/skaffold/build/local/docker_test.go +++ b/pkg/skaffold/build/local/docker_test.go @@ -58,6 +58,13 @@ func TestDockerCLIBuild(t *testing.T) { extraEnv: []string{"OTHER=VALUE"}, expectedEnv: []string{"KEY=VALUE", "OTHER=VALUE", "DOCKER_BUILDKIT=1"}, }, + { + description: "env var collisions", + localBuild: latest.LocalBuild{UseBuildkit: true}, + extraEnv: []string{"KEY=OTHER_VALUE", "DOCKER_BUILDKIT=0"}, + // env var collisions are handled by cmd.Run(). Last one wins. + expectedEnv: []string{"KEY=VALUE", "KEY=OTHER_VALUE", "DOCKER_BUILDKIT=0", "DOCKER_BUILDKIT=1"}, + }, } for _, test := range tests { From 9740c1ade3c49d6a60096e857904059e43e37384 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Wed, 28 Aug 2019 19:06:31 +0200 Subject: [PATCH 51/69] Restore original images only if there are no remote manifests Fixes #2690 Signed-off-by: David Gageot --- pkg/skaffold/deploy/kubectl.go | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/pkg/skaffold/deploy/kubectl.go b/pkg/skaffold/deploy/kubectl.go index a9ad476934c..751456af49c 100644 --- a/pkg/skaffold/deploy/kubectl.go +++ b/pkg/skaffold/deploy/kubectl.go @@ -149,22 +149,27 @@ func (k *KubectlDeployer) Cleanup(ctx context.Context, out io.Writer) error { return errors.Wrap(err, "reading manifests") } - // pull remote manifests - var rm deploy.ManifestList - for _, m := range k.RemoteManifests { - manifest, err := k.readRemoteManifest(ctx, m) + // revert remote manifests + // TODO(dgageot): That seems super dangerous and I don't understand + // why we need to update resources just before we delete them. + if len(k.RemoteManifests) > 0 { + var rm deploy.ManifestList + for _, m := range k.RemoteManifests { + manifest, err := k.readRemoteManifest(ctx, m) + if err != nil { + return errors.Wrap(err, "get remote manifests") + } + rm = append(rm, manifest) + } + upd, err := rm.ReplaceImages(k.originalImages, k.defaultRepo) if err != nil { - return errors.Wrap(err, "get remote manifests") + return errors.Wrap(err, "replacing with originals") + } + if err := k.kubectl.Apply(ctx, out, upd); err != nil { + return errors.Wrap(err, "apply original") } - rm = append(rm, manifest) - } - upd, err := rm.ReplaceImages(k.originalImages, k.defaultRepo) - if err != nil { - return errors.Wrap(err, "replacing with originals") - } - if err := k.kubectl.Apply(ctx, out, upd); err != nil { - return errors.Wrap(err, "apply original") } + if err := k.kubectl.Delete(ctx, out, manifests); err != nil { return errors.Wrap(err, "delete") } From d269a2b3ab7f0004c2cd422c744d67e12a8ddd52 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Wed, 28 Aug 2019 21:58:14 +0200 Subject: [PATCH 52/69] Improve manifest splitting. (#2727) Fix #2715 Signed-off-by: David Gageot --- pkg/skaffold/deploy/kubectl/manifests.go | 50 ++++++++++++-- pkg/skaffold/deploy/kubectl/manifests_test.go | 67 +++++++++++++++++-- 2 files changed, 103 insertions(+), 14 deletions(-) diff --git a/pkg/skaffold/deploy/kubectl/manifests.go b/pkg/skaffold/deploy/kubectl/manifests.go index c2b1de22ba3..204f7b1fb3f 100644 --- a/pkg/skaffold/deploy/kubectl/manifests.go +++ b/pkg/skaffold/deploy/kubectl/manifests.go @@ -38,17 +38,53 @@ func (l *ManifestList) String() string { } // Append appends the yaml manifests defined in the given buffer. +// `buf` can contain concatenated manifests without `---` separators +// because `kubectl create --dry-run -oyaml` produces such output. func (l *ManifestList) Append(buf []byte) { - // `kubectl create --dry-run -oyaml` outputs manifests without --- separator - // But we can rely on `apiVersion:` being here as a "separator". - buf = regexp. - MustCompile("\n(|---\n)apiVersion: "). - ReplaceAll(buf, []byte("\n---\napiVersion: ")) + // If there's at most one `apiVersion` field, then append the `buf` as is. + if len(regexp.MustCompile("(?m)^apiVersion:").FindAll(buf, -1)) <= 1 { + *l = append(*l, buf) + return + } + + // If there are `---` separators, then append each individual manifest as is. parts := bytes.Split(buf, []byte("\n---\n")) - for _, part := range parts { - *l = append(*l, part) + if len(parts) > 1 { + *l = append(*l, parts...) + return } + + // There are no `---` separators, let's identify each individual manifest + // based on the top level keys lexicographical order. + yaml := string(buf) + + var part string + var previousKey = "" + + for _, line := range strings.Split(yaml, "\n") { + // Not a top level key. + if strings.HasPrefix(line, " ") || !strings.Contains(line, ":") { + part += "\n" + line + continue + } + + // Top level key. + key := line[0:strings.Index(line, ":")] + if strings.Compare(key, previousKey) > 0 { + if part != "" { + part += "\n" + } + part += line + } else { + *l = append(*l, []byte(part)) + part = line + } + + previousKey = key + } + + *l = append(*l, []byte(part)) } // Diff computes the list of manifests that have changed. diff --git a/pkg/skaffold/deploy/kubectl/manifests_test.go b/pkg/skaffold/deploy/kubectl/manifests_test.go index df8a9c87a8d..d7604a3e394 100644 --- a/pkg/skaffold/deploy/kubectl/manifests_test.go +++ b/pkg/skaffold/deploy/kubectl/manifests_test.go @@ -38,24 +38,77 @@ metadata: spec: containers: - name: leeroy-app - image: leeroy-app` + image: leeroy-app` -func TestAppend(t *testing.T) { +const clusterRole = `aggregationRule: {} +apiVersion: v1 +kind: ClusterRole` + +const podUnordered = `kind: Pod +metadata: + name: leeroy-web +apiVersion: v1 +spec: + containers: + - name: leeroy-web + image: leeroy-web` + +func TestEmpty(t *testing.T) { var manifests ManifestList - manifests.Append([]byte(pod1 + "\n---\n" + pod2)) + testutil.CheckDeepEqual(t, 0, len(manifests)) - testutil.CheckDeepEqual(t, 2, len(manifests)) + manifests.Append(nil) + + testutil.CheckDeepEqual(t, 1, len(manifests)) +} + +func TestAppendSingle(t *testing.T) { + var manifests ManifestList + + manifests.Append([]byte(pod1)) + + testutil.CheckDeepEqual(t, 1, len(manifests)) + testutil.CheckDeepEqual(t, pod1, string(manifests[0])) +} + +func TestAppendUnordered(t *testing.T) { + var manifests ManifestList + + manifests.Append([]byte(podUnordered)) + + testutil.CheckDeepEqual(t, 1, len(manifests)) + testutil.CheckDeepEqual(t, podUnordered, string(manifests[0])) +} + +func TestAppendWithSeparators(t *testing.T) { + var manifests ManifestList + + manifests.Append([]byte(pod1 + "\n---\n" + pod2 + "\n---\n" + podUnordered)) + + testutil.CheckDeepEqual(t, 3, len(manifests)) testutil.CheckDeepEqual(t, pod1, string(manifests[0])) testutil.CheckDeepEqual(t, pod2, string(manifests[1])) + testutil.CheckDeepEqual(t, podUnordered, string(manifests[2])) } -func TestAppendWithoutSeperator(t *testing.T) { +func TestAppendWithoutSeparators(t *testing.T) { var manifests ManifestList - manifests.Append([]byte(pod1 + "\n" + pod2)) + manifests.Append([]byte(pod1 + "\n" + pod2 + "\n" + clusterRole)) - testutil.CheckDeepEqual(t, 2, len(manifests)) + testutil.CheckDeepEqual(t, 3, len(manifests)) testutil.CheckDeepEqual(t, pod1, string(manifests[0])) testutil.CheckDeepEqual(t, pod2, string(manifests[1])) + testutil.CheckDeepEqual(t, clusterRole, string(manifests[2])) +} + +func TestAppendDifferentApiVersion(t *testing.T) { + var manifests ManifestList + + manifests.Append([]byte("apiVersion: v1\napiVersion: v2")) + + testutil.CheckDeepEqual(t, 2, len(manifests)) + testutil.CheckDeepEqual(t, "apiVersion: v1", string(manifests[0])) + testutil.CheckDeepEqual(t, "apiVersion: v2", string(manifests[1])) } From 315b87061cb7164c3d4916c2662bf13fd9053251 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Wed, 28 Aug 2019 21:58:41 +0200 Subject: [PATCH 53/69] List manifests in the order given by the user (#2729) * List manifests in the order given by the user Fix #2645 Signed-off-by: David Gageot * s/list/set/ Signed-off-by: David Gageot --- pkg/skaffold/deploy/kubectl_test.go | 113 ++++++++++++++++++++-------- pkg/skaffold/util/util.go | 53 +++++++++---- pkg/skaffold/util/util_test.go | 7 +- 3 files changed, 125 insertions(+), 48 deletions(-) diff --git a/pkg/skaffold/deploy/kubectl_test.go b/pkg/skaffold/deploy/kubectl_test.go index b4fbf028052..5aa97231593 100644 --- a/pkg/skaffold/deploy/kubectl_test.go +++ b/pkg/skaffold/deploy/kubectl_test.go @@ -20,6 +20,7 @@ import ( "context" "fmt" "io/ioutil" + "path/filepath" "testing" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build" @@ -56,33 +57,18 @@ spec: func TestKubectlDeploy(t *testing.T) { tests := []struct { - description string - cfg *latest.KubectlDeploy - builds []build.Artifact - command util.Command - shouldErr bool - forceDeploy bool - expectedDependencies []string + description string + cfg *latest.KubectlDeploy + builds []build.Artifact + command util.Command + shouldErr bool + forceDeploy bool }{ { description: "no manifest", cfg: &latest.KubectlDeploy{}, command: testutil.FakeRunOut(t, "kubectl version --client -ojson", kubectlVersion), }, - { - description: "missing manifest file", - cfg: &latest.KubectlDeploy{ - Manifests: []string{"missing.yaml"}, - }, - command: testutil.FakeRunOut(t, "kubectl version --client -ojson", kubectlVersion), - }, - { - description: "ignore non-manifest", - cfg: &latest.KubectlDeploy{ - Manifests: []string{"*.ignored"}, - }, - command: testutil.FakeRunOut(t, "kubectl version --client -ojson", kubectlVersion), - }, { description: "deploy success (forced)", cfg: &latest.KubectlDeploy{ @@ -96,8 +82,7 @@ func TestKubectlDeploy(t *testing.T) { ImageName: "leeroy-web", Tag: "leeroy-web:123", }}, - forceDeploy: true, - expectedDependencies: []string{"deployment.yaml"}, + forceDeploy: true, }, { description: "deploy success", @@ -112,7 +97,6 @@ func TestKubectlDeploy(t *testing.T) { ImageName: "leeroy-web", Tag: "leeroy-web:123", }}, - expectedDependencies: []string{"deployment.yaml"}, }, { description: "http manifest", @@ -127,7 +111,6 @@ func TestKubectlDeploy(t *testing.T) { ImageName: "leeroy-web", Tag: "leeroy-web:123", }}, - expectedDependencies: []string{"deployment.yaml"}, }, { description: "deploy command error", @@ -142,8 +125,7 @@ func TestKubectlDeploy(t *testing.T) { ImageName: "leeroy-web", Tag: "leeroy-web:123", }}, - shouldErr: true, - expectedDependencies: []string{"deployment.yaml"}, + shouldErr: true, }, { description: "additional flags", @@ -163,8 +145,7 @@ func TestKubectlDeploy(t *testing.T) { ImageName: "leeroy-web", Tag: "leeroy-web:123", }}, - shouldErr: true, - expectedDependencies: []string{"deployment.yaml"}, + shouldErr: true, }, } for _, test := range tests { @@ -191,11 +172,8 @@ func TestKubectlDeploy(t *testing.T) { }, }) - dependencies, err := k.Dependencies() - t.CheckNoError(err) - t.CheckDeepEqual(test.expectedDependencies, dependencies) + err := k.Deploy(context.Background(), ioutil.Discard, test.builds, nil).GetError() - err = k.Deploy(context.Background(), ioutil.Discard, test.builds, nil).GetError() t.CheckError(test.shouldErr, err) }) } @@ -410,3 +388,72 @@ spec: t.CheckNoError(err) }) } + +func TestDependencies(t *testing.T) { + tests := []struct { + description string + manifests []string + expected []string + }{ + { + description: "no manifest", + manifests: []string(nil), + expected: []string(nil), + }, + { + description: "missing manifest file", + manifests: []string{"missing.yaml"}, + expected: []string(nil), + }, + { + description: "ignore non-manifest", + manifests: []string{"*.ignored"}, + expected: []string(nil), + }, + { + description: "single manifest", + manifests: []string{"deployment.yaml"}, + expected: []string{"deployment.yaml"}, + }, + { + description: "keep manifests order", + manifests: []string{"01_name.yaml", "00_service.yaml"}, + expected: []string{"01_name.yaml", "00_service.yaml"}, + }, + { + description: "sort children", + manifests: []string{"01/*.yaml", "00/*.yaml"}, + expected: []string{filepath.Join("01", "a.yaml"), filepath.Join("01", "b.yaml"), filepath.Join("00", "a.yaml"), filepath.Join("00", "b.yaml")}, + }, + { + description: "http manifest", + manifests: []string{"deployment.yaml", "http://remote.yaml"}, + expected: []string{"deployment.yaml"}, + }, + } + for _, test := range tests { + testutil.Run(t, test.description, func(t *testutil.T) { + t.NewTempDir(). + Touch("deployment.yaml", "01_name.yaml", "00_service.yaml", "empty.ignored"). + Touch("01/a.yaml", "01/b.yaml"). + Touch("00/b.yaml", "00/a.yaml"). + Chdir() + + k := NewKubectlDeployer(&runcontext.RunContext{ + Cfg: latest.Pipeline{ + Deploy: latest.DeployConfig{ + DeployType: latest.DeployType{ + KubectlDeploy: &latest.KubectlDeploy{ + Manifests: test.manifests, + }, + }, + }, + }, + }) + dependencies, err := k.Dependencies() + + t.CheckNoError(err) + t.CheckDeepEqual(test.expected, dependencies) + }) + } +} diff --git a/pkg/skaffold/util/util.go b/pkg/skaffold/util/util.go index e1ea58cb734..ee96cc83374 100644 --- a/pkg/skaffold/util/util.go +++ b/pkg/skaffold/util/util.go @@ -84,22 +84,45 @@ func StrSliceInsert(sl []string, index int, insert []string) []string { return newSlice } +// orderedFileSet holds an ordered set of file paths. +type orderedFileSet struct { + files []string + seen map[string]bool +} + +func (l *orderedFileSet) Add(file string) { + if l.seen[file] { + return + } + + if l.seen == nil { + l.seen = make(map[string]bool) + } + l.seen[file] = true + + l.files = append(l.files, file) +} + +func (l *orderedFileSet) Files() []string { + return l.files +} + // ExpandPathsGlob expands paths according to filepath.Glob patterns // Returns a list of unique files that match the glob patterns passed in. func ExpandPathsGlob(workingDir string, paths []string) ([]string, error) { - expandedPaths := make(map[string]bool) + var set orderedFileSet + for _, p := range paths { if filepath.IsAbs(p) { // This is a absolute file reference - expandedPaths[p] = true + set.Add(p) continue } path := filepath.Join(workingDir, p) - if _, err := os.Stat(path); err == nil { // This is a file reference, so just add it - expandedPaths[path] = true + set.Add(path) continue } @@ -112,25 +135,27 @@ func ExpandPathsGlob(workingDir string, paths []string) ([]string, error) { } for _, f := range files { - err := filepath.Walk(f, func(path string, info os.FileInfo, err error) error { + var filesInDirectory []string + + if err := filepath.Walk(f, func(path string, info os.FileInfo, err error) error { if !info.IsDir() { - expandedPaths[path] = true + filesInDirectory = append(filesInDirectory, path) } return nil - }) - if err != nil { + }); err != nil { return nil, errors.Wrap(err, "filepath walk") } + + // Make sure files inside a directory are listed in a consistent order + sort.Strings(filesInDirectory) + for _, file := range filesInDirectory { + set.Add(file) + } } } - var ret []string - for k := range expandedPaths { - ret = append(ret, k) - } - sort.Strings(ret) - return ret, nil + return set.Files(), nil } // BoolPtr returns a pointer to a bool diff --git a/pkg/skaffold/util/util_test.go b/pkg/skaffold/util/util_test.go index 01fb40289d7..eee0db9c30d 100644 --- a/pkg/skaffold/util/util_test.go +++ b/pkg/skaffold/util/util_test.go @@ -78,7 +78,7 @@ func TestExpandPathsGlob(t *testing.T) { out: []string{"dir/sub_dir/file"}, }, { - description: "match top level glob", + description: "top level glob", in: []string{"dir*"}, out: []string{"dir/sub_dir/file", "dir_b/sub_dir_b/file"}, }, @@ -87,6 +87,11 @@ func TestExpandPathsGlob(t *testing.T) { in: []string{"[]"}, shouldErr: true, }, + { + description: "keep top level order", + in: []string{"dir_b/*", "dir/*"}, + out: []string{"dir_b/sub_dir_b/file", "dir/sub_dir/file"}, + }, } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { From 9b14768902e4c8f0163055bc5fe50338b640b515 Mon Sep 17 00:00:00 2001 From: Nick Kubala Date: Mon, 26 Aug 2019 15:54:32 -0700 Subject: [PATCH 54/69] Use active gcloud credentials for executing cloudbuild when available --- go.sum | 1 + pkg/skaffold/build/cluster/sources/gcs.go | 7 ++- pkg/skaffold/build/gcb/cloud_build.go | 36 +++-------- pkg/skaffold/gcp/auth.go | 43 +++++++++++++ pkg/skaffold/gcp/client.go | 76 +++++++++++++++++++++++ pkg/skaffold/sources/upload.go | 8 +-- 6 files changed, 137 insertions(+), 34 deletions(-) create mode 100644 pkg/skaffold/gcp/client.go diff --git a/go.sum b/go.sum index f4c26468483..27b6379b328 100644 --- a/go.sum +++ b/go.sum @@ -349,6 +349,7 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0 h1:9sdfJOzWlkqPltHAuzT2Cp+yrBeY1KRVYgms8soxMwM= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= diff --git a/pkg/skaffold/build/cluster/sources/gcs.go b/pkg/skaffold/build/cluster/sources/gcs.go index 58c2b8dcab0..24e30e4aed3 100644 --- a/pkg/skaffold/build/cluster/sources/gcs.go +++ b/pkg/skaffold/build/cluster/sources/gcs.go @@ -51,7 +51,12 @@ func (g *GCSBucket) Setup(ctx context.Context, out io.Writer, artifact *latest.A color.Default.Fprintln(out, "Uploading sources to", bucket, "GCS bucket") g.tarName = fmt.Sprintf("context-%s.tar.gz", initialTag) - if err := sources.UploadToGCS(ctx, artifact, bucket, g.tarName, dependencies); err != nil { + c, err := gcp.CloudStorageClient() + if err != nil { + return "", errors.Wrap(err, "getting cloud storage client") + } + defer c.Close() + if err := sources.UploadToGCS(ctx, c, artifact, bucket, g.tarName, dependencies); err != nil { return "", errors.Wrap(err, "uploading sources to GCS") } diff --git a/pkg/skaffold/build/gcb/cloud_build.go b/pkg/skaffold/build/gcb/cloud_build.go index 0bb7262db4e..37fbdbb9181 100644 --- a/pkg/skaffold/build/gcb/cloud_build.go +++ b/pkg/skaffold/build/gcb/cloud_build.go @@ -35,7 +35,6 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/sources" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/version" "github.com/pkg/errors" "github.com/sirupsen/logrus" cloudbuild "google.golang.org/api/cloudbuild/v1" @@ -50,13 +49,12 @@ func (b *Builder) Build(ctx context.Context, out io.Writer, tags tag.ImageTags, } func (b *Builder) buildArtifactWithCloudBuild(ctx context.Context, out io.Writer, artifact *latest.Artifact, tag string) (string, error) { - cbclient, err := cloudbuild.NewService(ctx) + cbclient, err := gcp.CloudBuildClient() if err != nil { return "", errors.Wrap(err, "getting cloudbuild client") } - cbclient.UserAgent = version.UserAgent() - c, err := cstorage.NewClient(ctx) + c, err := gcp.CloudStorageClient() if err != nil { return "", errors.Wrap(err, "getting cloud storage client") } @@ -75,10 +73,10 @@ func (b *Builder) buildArtifactWithCloudBuild(ctx context.Context, out io.Writer cbBucket := fmt.Sprintf("%s%s", projectID, constants.GCSBucketSuffix) buildObject := fmt.Sprintf("source/%s-%s.tar.gz", projectID, util.RandomID()) - if err := b.createBucketIfNotExists(ctx, projectID, cbBucket); err != nil { + if err := b.createBucketIfNotExists(ctx, c, projectID, cbBucket); err != nil { return "", errors.Wrap(err, "creating bucket if not exists") } - if err := b.checkBucketProjectCorrect(ctx, projectID, cbBucket); err != nil { + if err := b.checkBucketProjectCorrect(ctx, c, projectID, cbBucket); err != nil { return "", errors.Wrap(err, "checking bucket is in correct project") } @@ -88,7 +86,7 @@ func (b *Builder) buildArtifactWithCloudBuild(ctx context.Context, out io.Writer } color.Default.Fprintf(out, "Pushing code to gs://%s/%s\n", cbBucket, buildObject) - if err := sources.UploadToGCS(ctx, artifact, cbBucket, buildObject, dependencies); err != nil { + if err := sources.UploadToGCS(ctx, c, artifact, cbBucket, buildObject, dependencies); err != nil { return "", errors.Wrap(err, "uploading source tarball") } @@ -136,7 +134,7 @@ watch: return "", errors.Wrap(err, "getting build status") } - r, err := b.getLogs(ctx, offset, cbBucket, logsObject) + r, err := b.getLogs(ctx, c, offset, cbBucket, logsObject) if err != nil { return "", errors.Wrap(err, "getting logs") } @@ -198,13 +196,7 @@ func getDigest(b *cloudbuild.Build, defaultToTag string) (string, error) { return docker.RemoteDigest(defaultToTag, nil) } -func (b *Builder) getLogs(ctx context.Context, offset int64, bucket, objectName string) (io.ReadCloser, error) { - c, err := cstorage.NewClient(ctx) - if err != nil { - return nil, errors.Wrap(err, "getting storage client") - } - defer c.Close() - +func (b *Builder) getLogs(ctx context.Context, c *cstorage.Client, offset int64, bucket, objectName string) (io.ReadCloser, error) { r, err := c.Bucket(bucket).Object(objectName).NewRangeReader(ctx, offset, -1) if err != nil { if gerr, ok := err.(*googleapi.Error); ok { @@ -224,11 +216,7 @@ func (b *Builder) getLogs(ctx context.Context, offset int64, bucket, objectName return r, nil } -func (b *Builder) checkBucketProjectCorrect(ctx context.Context, projectID, bucket string) error { - c, err := cstorage.NewClient(ctx) - if err != nil { - return errors.Wrap(err, "getting storage client") - } +func (b *Builder) checkBucketProjectCorrect(ctx context.Context, c *cstorage.Client, projectID, bucket string) error { it := c.Buckets(ctx, projectID) // Set the prefix to the bucket we're looking for to only return that bucket and buckets with that prefix // that we'll filter further later on @@ -248,12 +236,8 @@ func (b *Builder) checkBucketProjectCorrect(ctx context.Context, projectID, buck } } -func (b *Builder) createBucketIfNotExists(ctx context.Context, projectID, bucket string) error { - c, err := cstorage.NewClient(ctx) - if err != nil { - return errors.Wrap(err, "getting storage client") - } - defer c.Close() +func (b *Builder) createBucketIfNotExists(ctx context.Context, c *cstorage.Client, projectID, bucket string) error { + var err error _, err = c.Bucket(bucket).Attrs(ctx) diff --git a/pkg/skaffold/gcp/auth.go b/pkg/skaffold/gcp/auth.go index 694e439abbb..5ea360b2f36 100644 --- a/pkg/skaffold/gcp/auth.go +++ b/pkg/skaffold/gcp/auth.go @@ -17,11 +17,23 @@ limitations under the License. package gcp import ( + "context" + "encoding/json" "os/exec" "strings" + "sync" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/docker/cli/cli/config/configfile" + "github.com/pkg/errors" "github.com/sirupsen/logrus" + "golang.org/x/oauth2/google" +) + +var ( + creds *google.Credentials + credsOnce sync.Once + credsErr error ) // AutoConfigureGCRCredentialHelper automatically adds the `gcloud` credential helper @@ -50,3 +62,34 @@ func AutoConfigureGCRCredentialHelper(cf *configfile.ConfigFile, registry string } cf.CredentialHelpers[registry] = "gcloud" } + +func activeUserCredentials() (*google.Credentials, error) { + credsOnce.Do(func() { + cmd := exec.Command("gcloud", "auth", "print-access-token", "--format=json") + body, err := util.RunCmdOut(cmd) + if err != nil { + credsErr = errors.Wrap(err, "retrieving gcloud access token") + return + } + jsonCreds := make(map[string]interface{}) + json.Unmarshal(body, &jsonCreds) + jsonCreds["type"] = "authorized_user" + body, _ = json.Marshal(jsonCreds) + + c, err := google.CredentialsFromJSON(context.Background(), body) + if err != nil { + logrus.Infof("unable to retrieve google creds: %v", err) + logrus.Infof("falling back to application default credentials") + return + } + _, err = c.TokenSource.Token() + if err != nil { + logrus.Infof("unable to retrieve token: %v", err) + logrus.Infof("falling back to application default credentials") + return + } + creds = c + }) + + return creds, credsErr +} diff --git a/pkg/skaffold/gcp/client.go b/pkg/skaffold/gcp/client.go new file mode 100644 index 00000000000..b8e68a1748b --- /dev/null +++ b/pkg/skaffold/gcp/client.go @@ -0,0 +1,76 @@ +/* +Copyright 2019 The Skaffold 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 gcp + +import ( + "context" + "sync" + + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/version" + + cstorage "cloud.google.com/go/storage" + "github.com/pkg/errors" + cloudbuild "google.golang.org/api/cloudbuild/v1" + "google.golang.org/api/option" +) + +var ( + cbclient *cloudbuild.Service + cbOnce sync.Once + cbErr error +) + +// CloudBuildClient returns an authenticated client for interacting with +// the Google Cloud Build API. This client is created once and cached +// for repeated use in Skaffold. +func CloudBuildClient() (*cloudbuild.Service, error) { + cbOnce.Do(func() { + var options []option.ClientOption + var err error + creds, cErr := activeUserCredentials() + if cErr == nil && creds != nil { + options = append(options, option.WithCredentials(creds)) + } + + c, err := cloudbuild.NewService(context.Background(), options...) + if err != nil { + cbErr = err + return + } + c.UserAgent = version.UserAgent() + cbclient = c + }) + + return cbclient, cbErr +} + +// CloudStorageClient returns an authenticated client for interacting with +// the Google Cloud Storage API. This client is not cached by Skaffold, +// because it needs to be closed each time it is done being used by the caller. +func CloudStorageClient() (*cstorage.Client, error) { + var options []option.ClientOption + var err error + creds, cErr := activeUserCredentials() + if cErr == nil && creds != nil { + options = append(options, option.WithCredentials(creds)) + } + c, err := cstorage.NewClient(context.Background(), options...) + if err != nil { + return nil, errors.Wrap(err, "getting cloud storage client") + } + return c, nil +} diff --git a/pkg/skaffold/sources/upload.go b/pkg/skaffold/sources/upload.go index 2c2d44d3738..a4c8bf8b1be 100644 --- a/pkg/skaffold/sources/upload.go +++ b/pkg/skaffold/sources/upload.go @@ -36,13 +36,7 @@ func TarGz(ctx context.Context, w io.Writer, a *latest.Artifact, dependencies [] } // UploadToGCS uploads the artifact's sources to a GCS bucket. -func UploadToGCS(ctx context.Context, a *latest.Artifact, bucket, objectName string, dependencies []string) error { - c, err := cstorage.NewClient(ctx) - if err != nil { - return errors.Wrap(err, "creating GCS client") - } - defer c.Close() - +func UploadToGCS(ctx context.Context, c *cstorage.Client, a *latest.Artifact, bucket, objectName string, dependencies []string) error { w := c.Bucket(bucket).Object(objectName).NewWriter(ctx) if err := TarGz(ctx, w, a, dependencies); err != nil { return errors.Wrap(err, "uploading targz to google storage") From 22694df915c850803e8780c7bf4f81abd7c26d9b Mon Sep 17 00:00:00 2001 From: Brian de Alwis Date: Thu, 29 Aug 2019 05:31:01 -0400 Subject: [PATCH 55/69] Freeze v1beta13 and prepare v1beta14 (#2749) * Freeze v1beta13 and prepare v1beta14 * fix up version upgrade comments * improve new_version to show latest version --- docs/config.toml | 2 +- docs/content/en/schemas/v1beta14.json | 1921 +++++++++++++++++ hack/new_version.sh | 3 + integration/examples/bazel/skaffold.yaml | 2 +- .../examples/getting-started/skaffold.yaml | 2 +- .../examples/google-cloud-build/skaffold.yaml | 2 +- .../skaffold.yaml | 2 +- .../examples/helm-deployment/skaffold.yaml | 2 +- integration/examples/hot-reload/skaffold.yaml | 2 +- integration/examples/jib-gradle/skaffold.yaml | 2 +- .../examples/jib-multimodule/skaffold.yaml | 2 +- integration/examples/jib/skaffold.yaml | 2 +- .../examples/kaniko-local/skaffold.yaml | 2 +- integration/examples/kaniko/skaffold.yaml | 2 +- integration/examples/kustomize/skaffold.yaml | 2 +- .../examples/microservices/skaffold.yaml | 2 +- integration/examples/nodejs/skaffold.yaml | 2 +- .../examples/react-reload/skaffold.yaml | 2 +- .../examples/structure-tests/skaffold.yaml | 2 +- .../skaffold.yaml | 2 +- integration/testdata/build/skaffold.yaml | 2 +- integration/testdata/custom/skaffold.yaml | 2 +- integration/testdata/dev/skaffold.yaml | 2 +- .../testdata/gke_loadbalancer/skaffold.yaml | 2 +- integration/testdata/jib-gradle/skaffold.yaml | 2 +- integration/testdata/jib/skaffold.yaml | 2 +- .../kaniko-microservices/skaffold.yaml | 2 +- .../testdata/kaniko-sub-folder/skaffold.yaml | 2 +- .../testdata/kaniko-target/skaffold.yaml | 2 +- integration/testdata/tagPolicy/skaffold.yaml | 2 +- pkg/skaffold/schema/latest/config.go | 2 +- pkg/skaffold/schema/v1beta10/upgrade.go | 2 +- pkg/skaffold/schema/v1beta11/upgrade.go | 2 +- pkg/skaffold/schema/v1beta12/upgrade.go | 4 +- pkg/skaffold/schema/v1beta12/upgrade_test.go | 2 +- pkg/skaffold/schema/v1beta13/config.go | 772 +++++++ pkg/skaffold/schema/v1beta13/upgrade.go | 37 + pkg/skaffold/schema/v1beta13/upgrade_test.go | 149 ++ pkg/skaffold/schema/versions.go | 4 +- 39 files changed, 2919 insertions(+), 35 deletions(-) create mode 100755 docs/content/en/schemas/v1beta14.json create mode 100755 pkg/skaffold/schema/v1beta13/config.go create mode 100755 pkg/skaffold/schema/v1beta13/upgrade.go create mode 100755 pkg/skaffold/schema/v1beta13/upgrade_test.go diff --git a/docs/config.toml b/docs/config.toml index 562c28d6eff..379ee3a1209 100644 --- a/docs/config.toml +++ b/docs/config.toml @@ -70,7 +70,7 @@ weight = 1 #copyright = "Skaffold" #privacy_policy = "https://policies.google.com/privacy" github_repo = "https://github.com/GoogleContainerTools/skaffold" -skaffold_version = "skaffold/v1beta13" +skaffold_version = "skaffold/v1beta14" # Google Custom Search Engine ID. Remove or comment out to disable search. gcs_engine_id = "013756393218025596041:3nojel67sum" diff --git a/docs/content/en/schemas/v1beta14.json b/docs/content/en/schemas/v1beta14.json new file mode 100755 index 00000000000..9081192176a --- /dev/null +++ b/docs/content/en/schemas/v1beta14.json @@ -0,0 +1,1921 @@ +{ + "type": "object", + "anyOf": [ + { + "$ref": "#/definitions/SkaffoldConfig" + } + ], + "$schema": "http://json-schema-org/draft-07/schema#", + "definitions": { + "Activation": { + "properties": { + "command": { + "type": "string", + "description": "a Skaffold command for which the profile is auto-activated.", + "x-intellij-html-description": "a Skaffold command for which the profile is auto-activated.", + "examples": [ + "dev" + ] + }, + "env": { + "type": "string", + "description": "a `key=value` pair. The profile is auto-activated if an Environment Variable `key` has value `value`.", + "x-intellij-html-description": "a key=value pair. The profile is auto-activated if an Environment Variable key has value value.", + "examples": [ + "ENV=production" + ] + }, + "kubeContext": { + "type": "string", + "description": "a Kubernetes context for which the profile is auto-activated.", + "x-intellij-html-description": "a Kubernetes context for which the profile is auto-activated.", + "examples": [ + "minikube" + ] + } + }, + "preferredOrder": [ + "env", + "kubeContext", + "command" + ], + "additionalProperties": false, + "description": "criteria by which a profile is auto-activated.", + "x-intellij-html-description": "criteria by which a profile is auto-activated." + }, + "Artifact": { + "required": [ + "image" + ], + "anyOf": [ + { + "properties": { + "context": { + "type": "string", + "description": "directory containing the artifact's sources.", + "x-intellij-html-description": "directory containing the artifact's sources.", + "default": "." + }, + "image": { + "type": "string", + "description": "name of the image to be built.", + "x-intellij-html-description": "name of the image to be built.", + "examples": [ + "gcr.io/k8s-skaffold/example" + ] + }, + "sync": { + "$ref": "#/definitions/Sync", + "description": "*alpha* local files synced to pods instead of triggering an image build when modified.", + "x-intellij-html-description": "alpha local files synced to pods instead of triggering an image build when modified." + } + }, + "preferredOrder": [ + "image", + "context", + "sync" + ], + "additionalProperties": false + }, + { + "properties": { + "context": { + "type": "string", + "description": "directory containing the artifact's sources.", + "x-intellij-html-description": "directory containing the artifact's sources.", + "default": "." + }, + "docker": { + "$ref": "#/definitions/DockerArtifact", + "description": "*beta* describes an artifact built from a Dockerfile.", + "x-intellij-html-description": "beta describes an artifact built from a Dockerfile." + }, + "image": { + "type": "string", + "description": "name of the image to be built.", + "x-intellij-html-description": "name of the image to be built.", + "examples": [ + "gcr.io/k8s-skaffold/example" + ] + }, + "sync": { + "$ref": "#/definitions/Sync", + "description": "*alpha* local files synced to pods instead of triggering an image build when modified.", + "x-intellij-html-description": "alpha local files synced to pods instead of triggering an image build when modified." + } + }, + "preferredOrder": [ + "image", + "context", + "sync", + "docker" + ], + "additionalProperties": false + }, + { + "properties": { + "bazel": { + "$ref": "#/definitions/BazelArtifact", + "description": "*beta* requires bazel CLI to be installed and the sources to contain [Bazel](https://bazel.build/) configuration files.", + "x-intellij-html-description": "beta requires bazel CLI to be installed and the sources to contain Bazel configuration files." + }, + "context": { + "type": "string", + "description": "directory containing the artifact's sources.", + "x-intellij-html-description": "directory containing the artifact's sources.", + "default": "." + }, + "image": { + "type": "string", + "description": "name of the image to be built.", + "x-intellij-html-description": "name of the image to be built.", + "examples": [ + "gcr.io/k8s-skaffold/example" + ] + }, + "sync": { + "$ref": "#/definitions/Sync", + "description": "*alpha* local files synced to pods instead of triggering an image build when modified.", + "x-intellij-html-description": "alpha local files synced to pods instead of triggering an image build when modified." + } + }, + "preferredOrder": [ + "image", + "context", + "sync", + "bazel" + ], + "additionalProperties": false + }, + { + "properties": { + "context": { + "type": "string", + "description": "directory containing the artifact's sources.", + "x-intellij-html-description": "directory containing the artifact's sources.", + "default": "." + }, + "image": { + "type": "string", + "description": "name of the image to be built.", + "x-intellij-html-description": "name of the image to be built.", + "examples": [ + "gcr.io/k8s-skaffold/example" + ] + }, + "jibMaven": { + "$ref": "#/definitions/JibMavenArtifact", + "description": "*alpha* builds images using the [Jib plugin for Maven](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin).", + "x-intellij-html-description": "alpha builds images using the Jib plugin for Maven." + }, + "sync": { + "$ref": "#/definitions/Sync", + "description": "*alpha* local files synced to pods instead of triggering an image build when modified.", + "x-intellij-html-description": "alpha local files synced to pods instead of triggering an image build when modified." + } + }, + "preferredOrder": [ + "image", + "context", + "sync", + "jibMaven" + ], + "additionalProperties": false + }, + { + "properties": { + "context": { + "type": "string", + "description": "directory containing the artifact's sources.", + "x-intellij-html-description": "directory containing the artifact's sources.", + "default": "." + }, + "image": { + "type": "string", + "description": "name of the image to be built.", + "x-intellij-html-description": "name of the image to be built.", + "examples": [ + "gcr.io/k8s-skaffold/example" + ] + }, + "jibGradle": { + "$ref": "#/definitions/JibGradleArtifact", + "description": "*alpha* builds images using the [Jib plugin for Gradle](https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin).", + "x-intellij-html-description": "alpha builds images using the Jib plugin for Gradle." + }, + "sync": { + "$ref": "#/definitions/Sync", + "description": "*alpha* local files synced to pods instead of triggering an image build when modified.", + "x-intellij-html-description": "alpha local files synced to pods instead of triggering an image build when modified." + } + }, + "preferredOrder": [ + "image", + "context", + "sync", + "jibGradle" + ], + "additionalProperties": false + }, + { + "properties": { + "context": { + "type": "string", + "description": "directory containing the artifact's sources.", + "x-intellij-html-description": "directory containing the artifact's sources.", + "default": "." + }, + "image": { + "type": "string", + "description": "name of the image to be built.", + "x-intellij-html-description": "name of the image to be built.", + "examples": [ + "gcr.io/k8s-skaffold/example" + ] + }, + "kaniko": { + "$ref": "#/definitions/KanikoArtifact", + "description": "*alpha* builds images using [kaniko](https://github.com/GoogleContainerTools/kaniko).", + "x-intellij-html-description": "alpha builds images using kaniko." + }, + "sync": { + "$ref": "#/definitions/Sync", + "description": "*alpha* local files synced to pods instead of triggering an image build when modified.", + "x-intellij-html-description": "alpha local files synced to pods instead of triggering an image build when modified." + } + }, + "preferredOrder": [ + "image", + "context", + "sync", + "kaniko" + ], + "additionalProperties": false + }, + { + "properties": { + "context": { + "type": "string", + "description": "directory containing the artifact's sources.", + "x-intellij-html-description": "directory containing the artifact's sources.", + "default": "." + }, + "custom": { + "$ref": "#/definitions/CustomArtifact", + "description": "*alpha* builds images using a custom build script written by the user.", + "x-intellij-html-description": "alpha builds images using a custom build script written by the user." + }, + "image": { + "type": "string", + "description": "name of the image to be built.", + "x-intellij-html-description": "name of the image to be built.", + "examples": [ + "gcr.io/k8s-skaffold/example" + ] + }, + "sync": { + "$ref": "#/definitions/Sync", + "description": "*alpha* local files synced to pods instead of triggering an image build when modified.", + "x-intellij-html-description": "alpha local files synced to pods instead of triggering an image build when modified." + } + }, + "preferredOrder": [ + "image", + "context", + "sync", + "custom" + ], + "additionalProperties": false + } + ], + "description": "items that need to be built, along with the context in which they should be built.", + "x-intellij-html-description": "items that need to be built, along with the context in which they should be built." + }, + "BazelArtifact": { + "required": [ + "target" + ], + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array", + "description": "additional args to pass to `bazel build`.", + "x-intellij-html-description": "additional args to pass to bazel build.", + "default": "[]", + "examples": [ + "[\"-flag\", \"--otherflag\"]" + ] + }, + "target": { + "type": "string", + "description": "`bazel build` target to run.", + "x-intellij-html-description": "bazel build target to run.", + "examples": [ + "//:skaffold_example.tar" + ] + } + }, + "preferredOrder": [ + "target", + "args" + ], + "additionalProperties": false, + "description": "*beta* describes an artifact built with [Bazel](https://bazel.build/).", + "x-intellij-html-description": "beta describes an artifact built with Bazel." + }, + "BuildConfig": { + "anyOf": [ + { + "properties": { + "artifacts": { + "items": { + "$ref": "#/definitions/Artifact" + }, + "type": "array", + "description": "the images you're going to be building.", + "x-intellij-html-description": "the images you're going to be building." + }, + "insecureRegistries": { + "items": { + "type": "string" + }, + "type": "array", + "description": "a list of registries declared by the user to be insecure. These registries will be connected to via HTTP instead of HTTPS.", + "x-intellij-html-description": "a list of registries declared by the user to be insecure. These registries will be connected to via HTTP instead of HTTPS.", + "default": "[]" + }, + "tagPolicy": { + "$ref": "#/definitions/TagPolicy", + "description": "*beta* determines how images are tagged. A few strategies are provided here, although you most likely won't need to care! If not specified, it defaults to `gitCommit: {variant: Tags}`.", + "x-intellij-html-description": "beta determines how images are tagged. A few strategies are provided here, although you most likely won't need to care! If not specified, it defaults to gitCommit: {variant: Tags}." + } + }, + "preferredOrder": [ + "artifacts", + "insecureRegistries", + "tagPolicy" + ], + "additionalProperties": false + }, + { + "properties": { + "artifacts": { + "items": { + "$ref": "#/definitions/Artifact" + }, + "type": "array", + "description": "the images you're going to be building.", + "x-intellij-html-description": "the images you're going to be building." + }, + "insecureRegistries": { + "items": { + "type": "string" + }, + "type": "array", + "description": "a list of registries declared by the user to be insecure. These registries will be connected to via HTTP instead of HTTPS.", + "x-intellij-html-description": "a list of registries declared by the user to be insecure. These registries will be connected to via HTTP instead of HTTPS.", + "default": "[]" + }, + "local": { + "$ref": "#/definitions/LocalBuild", + "description": "*beta* describes how to do a build on the local docker daemon and optionally push to a repository.", + "x-intellij-html-description": "beta describes how to do a build on the local docker daemon and optionally push to a repository." + }, + "tagPolicy": { + "$ref": "#/definitions/TagPolicy", + "description": "*beta* determines how images are tagged. A few strategies are provided here, although you most likely won't need to care! If not specified, it defaults to `gitCommit: {variant: Tags}`.", + "x-intellij-html-description": "beta determines how images are tagged. A few strategies are provided here, although you most likely won't need to care! If not specified, it defaults to gitCommit: {variant: Tags}." + } + }, + "preferredOrder": [ + "artifacts", + "insecureRegistries", + "tagPolicy", + "local" + ], + "additionalProperties": false + }, + { + "properties": { + "artifacts": { + "items": { + "$ref": "#/definitions/Artifact" + }, + "type": "array", + "description": "the images you're going to be building.", + "x-intellij-html-description": "the images you're going to be building." + }, + "googleCloudBuild": { + "$ref": "#/definitions/GoogleCloudBuild", + "description": "*beta* describes how to do a remote build on [Google Cloud Build](https://cloud.google.com/cloud-build/).", + "x-intellij-html-description": "beta describes how to do a remote build on Google Cloud Build." + }, + "insecureRegistries": { + "items": { + "type": "string" + }, + "type": "array", + "description": "a list of registries declared by the user to be insecure. These registries will be connected to via HTTP instead of HTTPS.", + "x-intellij-html-description": "a list of registries declared by the user to be insecure. These registries will be connected to via HTTP instead of HTTPS.", + "default": "[]" + }, + "tagPolicy": { + "$ref": "#/definitions/TagPolicy", + "description": "*beta* determines how images are tagged. A few strategies are provided here, although you most likely won't need to care! If not specified, it defaults to `gitCommit: {variant: Tags}`.", + "x-intellij-html-description": "beta determines how images are tagged. A few strategies are provided here, although you most likely won't need to care! If not specified, it defaults to gitCommit: {variant: Tags}." + } + }, + "preferredOrder": [ + "artifacts", + "insecureRegistries", + "tagPolicy", + "googleCloudBuild" + ], + "additionalProperties": false + }, + { + "properties": { + "artifacts": { + "items": { + "$ref": "#/definitions/Artifact" + }, + "type": "array", + "description": "the images you're going to be building.", + "x-intellij-html-description": "the images you're going to be building." + }, + "cluster": { + "$ref": "#/definitions/ClusterDetails", + "description": "*beta* describes how to do an on-cluster build.", + "x-intellij-html-description": "beta describes how to do an on-cluster build." + }, + "insecureRegistries": { + "items": { + "type": "string" + }, + "type": "array", + "description": "a list of registries declared by the user to be insecure. These registries will be connected to via HTTP instead of HTTPS.", + "x-intellij-html-description": "a list of registries declared by the user to be insecure. These registries will be connected to via HTTP instead of HTTPS.", + "default": "[]" + }, + "tagPolicy": { + "$ref": "#/definitions/TagPolicy", + "description": "*beta* determines how images are tagged. A few strategies are provided here, although you most likely won't need to care! If not specified, it defaults to `gitCommit: {variant: Tags}`.", + "x-intellij-html-description": "beta determines how images are tagged. A few strategies are provided here, although you most likely won't need to care! If not specified, it defaults to gitCommit: {variant: Tags}." + } + }, + "preferredOrder": [ + "artifacts", + "insecureRegistries", + "tagPolicy", + "cluster" + ], + "additionalProperties": false + } + ], + "description": "contains all the configuration for the build steps.", + "x-intellij-html-description": "contains all the configuration for the build steps." + }, + "ClusterDetails": { + "properties": { + "HTTPS_PROXY": { + "type": "string", + "description": "for kaniko pod.", + "x-intellij-html-description": "for kaniko pod." + }, + "HTTP_PROXY": { + "type": "string", + "description": "for kaniko pod.", + "x-intellij-html-description": "for kaniko pod." + }, + "dockerConfig": { + "$ref": "#/definitions/DockerConfig", + "description": "describes how to mount the local Docker configuration into a pod.", + "x-intellij-html-description": "describes how to mount the local Docker configuration into a pod." + }, + "namespace": { + "type": "string", + "description": "Kubernetes namespace. Defaults to current namespace in Kubernetes configuration.", + "x-intellij-html-description": "Kubernetes namespace. Defaults to current namespace in Kubernetes configuration." + }, + "pullSecret": { + "type": "string", + "description": "path to the Google Cloud service account secret key file.", + "x-intellij-html-description": "path to the Google Cloud service account secret key file." + }, + "pullSecretName": { + "type": "string", + "description": "name of the Kubernetes secret for pulling the files from the build context and pushing the final image. If given, the secret needs to contain the Google Cloud service account secret key under the key `kaniko-secret`.", + "x-intellij-html-description": "name of the Kubernetes secret for pulling the files from the build context and pushing the final image. If given, the secret needs to contain the Google Cloud service account secret key under the key kaniko-secret.", + "default": "kaniko-secret" + }, + "resources": { + "$ref": "#/definitions/ResourceRequirements", + "description": "define the resource requirements for the kaniko pod.", + "x-intellij-html-description": "define the resource requirements for the kaniko pod." + }, + "timeout": { + "type": "string", + "description": "amount of time (in seconds) that this build is allowed to run. Defaults to 20 minutes (`20m`).", + "x-intellij-html-description": "amount of time (in seconds) that this build is allowed to run. Defaults to 20 minutes (20m)." + } + }, + "preferredOrder": [ + "HTTP_PROXY", + "HTTPS_PROXY", + "pullSecret", + "pullSecretName", + "namespace", + "timeout", + "dockerConfig", + "resources" + ], + "additionalProperties": false, + "description": "*beta* describes how to do an on-cluster build.", + "x-intellij-html-description": "beta describes how to do an on-cluster build." + }, + "CustomArtifact": { + "properties": { + "buildCommand": { + "type": "string", + "description": "command executed to build the image.", + "x-intellij-html-description": "command executed to build the image." + }, + "dependencies": { + "$ref": "#/definitions/CustomDependencies", + "description": "file dependencies that skaffold should watch for both rebuilding and file syncing for this artifact.", + "x-intellij-html-description": "file dependencies that skaffold should watch for both rebuilding and file syncing for this artifact." + } + }, + "preferredOrder": [ + "buildCommand", + "dependencies" + ], + "additionalProperties": false, + "description": "*alpha* describes an artifact built from a custom build script written by the user. It can be used to build images with builders that aren't directly integrated with skaffold.", + "x-intellij-html-description": "alpha describes an artifact built from a custom build script written by the user. It can be used to build images with builders that aren't directly integrated with skaffold." + }, + "CustomDependencies": { + "properties": { + "command": { + "type": "string", + "description": "represents a custom command that skaffold executes to obtain dependencies. The output of this command *must* be a valid JSON array.", + "x-intellij-html-description": "represents a custom command that skaffold executes to obtain dependencies. The output of this command must be a valid JSON array." + }, + "dockerfile": { + "$ref": "#/definitions/DockerfileDependency", + "description": "should be set if the artifact is built from a Dockerfile, from which skaffold can determine dependencies.", + "x-intellij-html-description": "should be set if the artifact is built from a Dockerfile, from which skaffold can determine dependencies." + }, + "ignore": { + "items": { + "type": "string" + }, + "type": "array", + "description": "specifies the paths that should be ignored by skaffold's file watcher. If a file exists in both `paths` and in `ignore`, it will be ignored, and will be excluded from both rebuilds and file synchronization. Will only work in conjunction with `paths`.", + "x-intellij-html-description": "specifies the paths that should be ignored by skaffold's file watcher. If a file exists in both paths and in ignore, it will be ignored, and will be excluded from both rebuilds and file synchronization. Will only work in conjunction with paths.", + "default": "[]" + }, + "paths": { + "items": { + "type": "string" + }, + "type": "array", + "description": "should be set to the file dependencies for this artifact, so that the skaffold file watcher knows when to rebuild and perform file synchronization.", + "x-intellij-html-description": "should be set to the file dependencies for this artifact, so that the skaffold file watcher knows when to rebuild and perform file synchronization.", + "default": "[]" + } + }, + "preferredOrder": [ + "dockerfile", + "command", + "paths", + "ignore" + ], + "additionalProperties": false, + "description": "*alpha* used to specify dependencies for an artifact built by a custom build script. Either `dockerfile` or `paths` should be specified for file watching to work as expected.", + "x-intellij-html-description": "alpha used to specify dependencies for an artifact built by a custom build script. Either dockerfile or paths should be specified for file watching to work as expected." + }, + "DateTimeTagger": { + "properties": { + "format": { + "type": "string", + "description": "formats the date and time. See [#Time.Format](https://golang.org/pkg/time/#Time.Format).", + "x-intellij-html-description": "formats the date and time. See #Time.Format.", + "default": "2006-01-02_15-04-05.999_MST" + }, + "timezone": { + "type": "string", + "description": "sets the timezone for the date and time. See [Time.LoadLocation](https://golang.org/pkg/time/#Time.LoadLocation). Defaults to the local timezone.", + "x-intellij-html-description": "sets the timezone for the date and time. See Time.LoadLocation. Defaults to the local timezone." + } + }, + "preferredOrder": [ + "format", + "timezone" + ], + "additionalProperties": false, + "description": "*beta* tags images with the build timestamp.", + "x-intellij-html-description": "beta tags images with the build timestamp." + }, + "DeployConfig": { + "anyOf": [ + { + "properties": { + "statusCheckDeadlineSeconds": { + "type": "integer", + "description": "*beta* deadline for deployments to stabilize in seconds.", + "x-intellij-html-description": "beta deadline for deployments to stabilize in seconds." + } + }, + "preferredOrder": [ + "statusCheckDeadlineSeconds" + ], + "additionalProperties": false + }, + { + "properties": { + "helm": { + "$ref": "#/definitions/HelmDeploy", + "description": "*beta* uses the `helm` CLI to apply the charts to the cluster.", + "x-intellij-html-description": "beta uses the helm CLI to apply the charts to the cluster." + }, + "statusCheckDeadlineSeconds": { + "type": "integer", + "description": "*beta* deadline for deployments to stabilize in seconds.", + "x-intellij-html-description": "beta deadline for deployments to stabilize in seconds." + } + }, + "preferredOrder": [ + "statusCheckDeadlineSeconds", + "helm" + ], + "additionalProperties": false + }, + { + "properties": { + "kubectl": { + "$ref": "#/definitions/KubectlDeploy", + "description": "*beta* uses a client side `kubectl apply` to deploy manifests. You'll need a `kubectl` CLI version installed that's compatible with your cluster.", + "x-intellij-html-description": "beta uses a client side kubectl apply to deploy manifests. You'll need a kubectl CLI version installed that's compatible with your cluster." + }, + "statusCheckDeadlineSeconds": { + "type": "integer", + "description": "*beta* deadline for deployments to stabilize in seconds.", + "x-intellij-html-description": "beta deadline for deployments to stabilize in seconds." + } + }, + "preferredOrder": [ + "statusCheckDeadlineSeconds", + "kubectl" + ], + "additionalProperties": false + }, + { + "properties": { + "kustomize": { + "$ref": "#/definitions/KustomizeDeploy", + "description": "*beta* uses the `kustomize` CLI to \"patch\" a deployment for a target environment.", + "x-intellij-html-description": "beta uses the kustomize CLI to "patch" a deployment for a target environment." + }, + "statusCheckDeadlineSeconds": { + "type": "integer", + "description": "*beta* deadline for deployments to stabilize in seconds.", + "x-intellij-html-description": "beta deadline for deployments to stabilize in seconds." + } + }, + "preferredOrder": [ + "statusCheckDeadlineSeconds", + "kustomize" + ], + "additionalProperties": false + } + ], + "description": "contains all the configuration needed by the deploy steps.", + "x-intellij-html-description": "contains all the configuration needed by the deploy steps." + }, + "DockerArtifact": { + "properties": { + "buildArgs": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "description": "arguments passed to the docker build.", + "x-intellij-html-description": "arguments passed to the docker build.", + "default": "{}", + "examples": [ + "{\"key1\": \"value1\", \"key2\": \"value2\"}" + ] + }, + "cacheFrom": { + "items": { + "type": "string" + }, + "type": "array", + "description": "the Docker images used as cache sources.", + "x-intellij-html-description": "the Docker images used as cache sources.", + "default": "[]", + "examples": [ + "[\"golang:1.10.1-alpine3.7\", \"alpine:3.7\"]" + ] + }, + "dockerfile": { + "type": "string", + "description": "locates the Dockerfile relative to workspace.", + "x-intellij-html-description": "locates the Dockerfile relative to workspace.", + "default": "Dockerfile" + }, + "network": { + "type": "string", + "description": "passed through to docker and overrides the network configuration of docker builder. If unset, use whatever is configured in the underlying docker daemon. Valid modes are `host`: use the host's networking stack. `bridge`: use the bridged network configuration. `none`: no networking in the container.", + "x-intellij-html-description": "passed through to docker and overrides the network configuration of docker builder. If unset, use whatever is configured in the underlying docker daemon. Valid modes are host: use the host's networking stack. bridge: use the bridged network configuration. none: no networking in the container." + }, + "noCache": { + "type": "boolean", + "description": "used to pass in --no-cache to docker build to prevent caching.", + "x-intellij-html-description": "used to pass in --no-cache to docker build to prevent caching.", + "default": "false" + }, + "target": { + "type": "string", + "description": "Dockerfile target name to build.", + "x-intellij-html-description": "Dockerfile target name to build." + } + }, + "preferredOrder": [ + "dockerfile", + "target", + "buildArgs", + "network", + "cacheFrom", + "noCache" + ], + "additionalProperties": false, + "description": "*beta* describes an artifact built from a Dockerfile, usually using `docker build`.", + "x-intellij-html-description": "beta describes an artifact built from a Dockerfile, usually using docker build." + }, + "DockerConfig": { + "properties": { + "path": { + "type": "string", + "description": "path to the docker `config.json`.", + "x-intellij-html-description": "path to the docker config.json." + }, + "secretName": { + "type": "string", + "description": "Kubernetes secret that contains the `config.json` Docker configuration. Note that the expected secret type is not 'kubernetes.io/dockerconfigjson' but 'Opaque'.", + "x-intellij-html-description": "Kubernetes secret that contains the config.json Docker configuration. Note that the expected secret type is not 'kubernetes.io/dockerconfigjson' but 'Opaque'." + } + }, + "preferredOrder": [ + "path", + "secretName" + ], + "additionalProperties": false, + "description": "contains information about the docker `config.json` to mount.", + "x-intellij-html-description": "contains information about the docker config.json to mount." + }, + "DockerfileDependency": { + "properties": { + "buildArgs": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "description": "arguments passed to the docker build. It also accepts environment variables via the go template syntax.", + "x-intellij-html-description": "arguments passed to the docker build. It also accepts environment variables via the go template syntax.", + "default": "{}", + "examples": [ + "{\"key1\": \"value1\", \"key2\": \"value2\", \"key3\": \"{{.ENV_VARIABLE}}\"}" + ] + }, + "path": { + "type": "string", + "description": "locates the Dockerfile relative to workspace.", + "x-intellij-html-description": "locates the Dockerfile relative to workspace." + } + }, + "preferredOrder": [ + "path", + "buildArgs" + ], + "additionalProperties": false, + "description": "*alpha* used to specify a custom build artifact that is built from a Dockerfile. This allows skaffold to determine dependencies from the Dockerfile.", + "x-intellij-html-description": "alpha used to specify a custom build artifact that is built from a Dockerfile. This allows skaffold to determine dependencies from the Dockerfile." + }, + "EnvTemplateTagger": { + "required": [ + "template" + ], + "properties": { + "template": { + "type": "string", + "description": "used to produce the image name and tag. See golang [text/template](https://golang.org/pkg/text/template/). The template is executed against the current environment, with those variables injected: IMAGE_NAME | Name of the image being built, as supplied in the artifacts section.", + "x-intellij-html-description": "used to produce the image name and tag. See golang text/template. The template is executed against the current environment, with those variables injected: IMAGE_NAME | Name of the image being built, as supplied in the artifacts section.", + "examples": [ + "{{.RELEASE}}-{{.IMAGE_NAME}}" + ] + } + }, + "preferredOrder": [ + "template" + ], + "additionalProperties": false, + "description": "*beta* tags images with a configurable template string.", + "x-intellij-html-description": "beta tags images with a configurable template string." + }, + "GitTagger": { + "properties": { + "variant": { + "type": "string", + "description": "determines the behavior of the git tagger. Valid variants are `Tags` (default): use git tags or fall back to abbreviated commit hash. `CommitSha`: use the full git commit sha. `AbbrevCommitSha`: use the abbreviated git commit sha. `TreeSha`: use the full tree hash of the artifact workingdir. `AbbrevTreeSha`: use the abbreviated tree hash of the artifact workingdir.", + "x-intellij-html-description": "determines the behavior of the git tagger. Valid variants are Tags (default): use git tags or fall back to abbreviated commit hash. CommitSha: use the full git commit sha. AbbrevCommitSha: use the abbreviated git commit sha. TreeSha: use the full tree hash of the artifact workingdir. AbbrevTreeSha: use the abbreviated tree hash of the artifact workingdir." + } + }, + "preferredOrder": [ + "variant" + ], + "additionalProperties": false, + "description": "*beta* tags images with the git tag or commit of the artifact's workspace.", + "x-intellij-html-description": "beta tags images with the git tag or commit of the artifact's workspace." + }, + "GoogleCloudBuild": { + "properties": { + "diskSizeGb": { + "type": "integer", + "description": "disk size of the VM that runs the build. See [Cloud Build Reference](https://cloud.google.com/cloud-build/docs/api/reference/rest/v1/projects.builds#buildoptions).", + "x-intellij-html-description": "disk size of the VM that runs the build. See Cloud Build Reference." + }, + "dockerImage": { + "type": "string", + "description": "image that runs a Docker build. See [Cloud Builders](https://cloud.google.com/cloud-build/docs/cloud-builders).", + "x-intellij-html-description": "image that runs a Docker build. See Cloud Builders.", + "default": "gcr.io/cloud-builders/docker" + }, + "gradleImage": { + "type": "string", + "description": "image that runs a Gradle build. See [Cloud Builders](https://cloud.google.com/cloud-build/docs/cloud-builders).", + "x-intellij-html-description": "image that runs a Gradle build. See Cloud Builders.", + "default": "gcr.io/cloud-builders/gradle" + }, + "machineType": { + "type": "string", + "description": "type of the VM that runs the build. See [Cloud Build Reference](https://cloud.google.com/cloud-build/docs/api/reference/rest/v1/projects.builds#buildoptions).", + "x-intellij-html-description": "type of the VM that runs the build. See Cloud Build Reference." + }, + "mavenImage": { + "type": "string", + "description": "image that runs a Maven build. See [Cloud Builders](https://cloud.google.com/cloud-build/docs/cloud-builders).", + "x-intellij-html-description": "image that runs a Maven build. See Cloud Builders.", + "default": "gcr.io/cloud-builders/mvn" + }, + "projectId": { + "type": "string", + "description": "ID of your Cloud Platform Project. If it is not provided, Skaffold will guess it from the image name. For example, given the artifact image name `gcr.io/myproject/image`, Skaffold will use the `myproject` GCP project.", + "x-intellij-html-description": "ID of your Cloud Platform Project. If it is not provided, Skaffold will guess it from the image name. For example, given the artifact image name gcr.io/myproject/image, Skaffold will use the myproject GCP project." + }, + "timeout": { + "type": "string", + "description": "amount of time (in seconds) that this build should be allowed to run. See [Cloud Build Reference](https://cloud.google.com/cloud-build/docs/api/reference/rest/v1/projects.builds#resource-build).", + "x-intellij-html-description": "amount of time (in seconds) that this build should be allowed to run. See Cloud Build Reference." + } + }, + "preferredOrder": [ + "projectId", + "diskSizeGb", + "machineType", + "timeout", + "dockerImage", + "mavenImage", + "gradleImage" + ], + "additionalProperties": false, + "description": "*beta* describes how to do a remote build on [Google Cloud Build](https://cloud.google.com/cloud-build/docs/). Docker and Jib artifacts can be built on Cloud Build. The `projectId` needs to be provided and the currently logged in user should be given permissions to trigger new builds.", + "x-intellij-html-description": "beta describes how to do a remote build on Google Cloud Build. Docker and Jib artifacts can be built on Cloud Build. The projectId needs to be provided and the currently logged in user should be given permissions to trigger new builds." + }, + "HelmConventionConfig": { + "properties": { + "explicitRegistry": { + "type": "boolean", + "description": "separates `image.registry` to the image config syntax. Useful for some charts e.g. `postgresql`.", + "x-intellij-html-description": "separates image.registry to the image config syntax. Useful for some charts e.g. postgresql.", + "default": "false" + } + }, + "preferredOrder": [ + "explicitRegistry" + ], + "additionalProperties": false, + "description": "image config in the syntax of image.repository and image.tag.", + "x-intellij-html-description": "image config in the syntax of image.repository and image.tag." + }, + "HelmDeploy": { + "required": [ + "releases" + ], + "properties": { + "flags": { + "$ref": "#/definitions/HelmDeployFlags", + "description": "additional option flags that are passed on the command line to `helm`.", + "x-intellij-html-description": "additional option flags that are passed on the command line to helm." + }, + "releases": { + "items": { + "$ref": "#/definitions/HelmRelease" + }, + "type": "array", + "description": "a list of Helm releases.", + "x-intellij-html-description": "a list of Helm releases." + } + }, + "preferredOrder": [ + "releases", + "flags" + ], + "additionalProperties": false, + "description": "*beta* uses the `helm` CLI to apply the charts to the cluster.", + "x-intellij-html-description": "beta uses the helm CLI to apply the charts to the cluster." + }, + "HelmDeployFlags": { + "properties": { + "global": { + "items": { + "type": "string" + }, + "type": "array", + "description": "additional flags passed on every command.", + "x-intellij-html-description": "additional flags passed on every command.", + "default": "[]" + }, + "install": { + "items": { + "type": "string" + }, + "type": "array", + "description": "additional flags passed to (`helm install`).", + "x-intellij-html-description": "additional flags passed to (helm install).", + "default": "[]" + }, + "upgrade": { + "items": { + "type": "string" + }, + "type": "array", + "description": "additional flags passed to (`helm upgrade`).", + "x-intellij-html-description": "additional flags passed to (helm upgrade).", + "default": "[]" + } + }, + "preferredOrder": [ + "global", + "install", + "upgrade" + ], + "additionalProperties": false, + "description": "additional option flags that are passed on the command line to `helm`.", + "x-intellij-html-description": "additional option flags that are passed on the command line to helm." + }, + "HelmFQNConfig": { + "properties": { + "property": { + "type": "string", + "description": "defines the image config.", + "x-intellij-html-description": "defines the image config." + } + }, + "preferredOrder": [ + "property" + ], + "additionalProperties": false, + "description": "image config to use the FullyQualifiedImageName as param to set.", + "x-intellij-html-description": "image config to use the FullyQualifiedImageName as param to set." + }, + "HelmImageStrategy": { + "anyOf": [ + { + "additionalProperties": false + }, + { + "properties": { + "fqn": { + "$ref": "#/definitions/HelmFQNConfig", + "description": "image configuration uses the syntax `IMAGE-NAME=IMAGE-REPOSITORY:IMAGE-TAG`.", + "x-intellij-html-description": "image configuration uses the syntax IMAGE-NAME=IMAGE-REPOSITORY:IMAGE-TAG." + } + }, + "preferredOrder": [ + "fqn" + ], + "additionalProperties": false + }, + { + "properties": { + "helm": { + "$ref": "#/definitions/HelmConventionConfig", + "description": "image configuration uses the syntax `IMAGE-NAME.repository=IMAGE-REPOSITORY, IMAGE-NAME.tag=IMAGE-TAG`.", + "x-intellij-html-description": "image configuration uses the syntax IMAGE-NAME.repository=IMAGE-REPOSITORY, IMAGE-NAME.tag=IMAGE-TAG." + } + }, + "preferredOrder": [ + "helm" + ], + "additionalProperties": false + } + ], + "description": "adds image configurations to the Helm `values` file.", + "x-intellij-html-description": "adds image configurations to the Helm values file." + }, + "HelmPackaged": { + "properties": { + "appVersion": { + "type": "string", + "description": "sets the `appVersion` on the chart to this version.", + "x-intellij-html-description": "sets the appVersion on the chart to this version." + }, + "version": { + "type": "string", + "description": "sets the `version` on the chart to this semver version.", + "x-intellij-html-description": "sets the version on the chart to this semver version." + } + }, + "preferredOrder": [ + "version", + "appVersion" + ], + "additionalProperties": false, + "description": "parameters for packaging helm chart (`helm package`).", + "x-intellij-html-description": "parameters for packaging helm chart (helm package)." + }, + "HelmRelease": { + "required": [ + "name", + "chartPath" + ], + "properties": { + "chartPath": { + "type": "string", + "description": "path to the Helm chart.", + "x-intellij-html-description": "path to the Helm chart." + }, + "imageStrategy": { + "$ref": "#/definitions/HelmImageStrategy", + "description": "adds image configurations to the Helm `values` file.", + "x-intellij-html-description": "adds image configurations to the Helm values file." + }, + "name": { + "type": "string", + "description": "name of the Helm release.", + "x-intellij-html-description": "name of the Helm release." + }, + "namespace": { + "type": "string", + "description": "Kubernetes namespace.", + "x-intellij-html-description": "Kubernetes namespace." + }, + "overrides": { + "description": "key-value pairs. If present, Skaffold will build a Helm `values` file that overrides the original and use it to call Helm CLI (`--f` flag).", + "x-intellij-html-description": "key-value pairs. If present, Skaffold will build a Helm values file that overrides the original and use it to call Helm CLI (--f flag)." + }, + "packaged": { + "$ref": "#/definitions/HelmPackaged", + "description": "parameters for packaging helm chart (`helm package`).", + "x-intellij-html-description": "parameters for packaging helm chart (helm package)." + }, + "recreatePods": { + "type": "boolean", + "description": "if `true`, Skaffold will send `--recreate-pods` flag to Helm CLI.", + "x-intellij-html-description": "if true, Skaffold will send --recreate-pods flag to Helm CLI.", + "default": "false" + }, + "remote": { + "type": "boolean", + "description": "specifies whether the chart path is remote, or exists on the host filesystem. `remote: true` implies `skipBuildDependencies: true`.", + "x-intellij-html-description": "specifies whether the chart path is remote, or exists on the host filesystem. remote: true implies skipBuildDependencies: true.", + "default": "false" + }, + "setValueTemplates": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "description": "key-value pairs. If present, Skaffold will try to parse the value part of each key-value pair using environment variables in the system, then send `--set` flag to Helm CLI and append all parsed pairs after the flag.", + "x-intellij-html-description": "key-value pairs. If present, Skaffold will try to parse the value part of each key-value pair using environment variables in the system, then send --set flag to Helm CLI and append all parsed pairs after the flag.", + "default": "{}" + }, + "setValues": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "description": "key-value pairs. If present, Skaffold will send `--set` flag to Helm CLI and append all pairs after the flag.", + "x-intellij-html-description": "key-value pairs. If present, Skaffold will send --set flag to Helm CLI and append all pairs after the flag.", + "default": "{}" + }, + "skipBuildDependencies": { + "type": "boolean", + "description": "should build dependencies be skipped.", + "x-intellij-html-description": "should build dependencies be skipped.", + "default": "false" + }, + "useHelmSecrets": { + "type": "boolean", + "description": "instructs skaffold to use secrets plugin on deployment.", + "x-intellij-html-description": "instructs skaffold to use secrets plugin on deployment.", + "default": "false" + }, + "values": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "description": "key-value pairs supplementing the Helm `values` file.", + "x-intellij-html-description": "key-value pairs supplementing the Helm values file.", + "default": "{}" + }, + "valuesFiles": { + "items": { + "type": "string" + }, + "type": "array", + "description": "paths to the Helm `values` files.", + "x-intellij-html-description": "paths to the Helm values files.", + "default": "[]" + }, + "version": { + "type": "string", + "description": "version of the chart.", + "x-intellij-html-description": "version of the chart." + }, + "wait": { + "type": "boolean", + "description": "if `true`, Skaffold will send `--wait` flag to Helm CLI.", + "x-intellij-html-description": "if true, Skaffold will send --wait flag to Helm CLI.", + "default": "false" + } + }, + "preferredOrder": [ + "name", + "chartPath", + "valuesFiles", + "values", + "namespace", + "version", + "setValues", + "setValueTemplates", + "wait", + "recreatePods", + "skipBuildDependencies", + "useHelmSecrets", + "remote", + "overrides", + "packaged", + "imageStrategy" + ], + "additionalProperties": false, + "description": "describes a helm release to be deployed.", + "x-intellij-html-description": "describes a helm release to be deployed." + }, + "JSONPatch": { + "required": [ + "path" + ], + "properties": { + "from": { + "type": "string", + "description": "source position in the yaml, used for `copy` or `move` operations.", + "x-intellij-html-description": "source position in the yaml, used for copy or move operations." + }, + "op": { + "type": "string", + "description": "operation carried by the patch: `add`, `remove`, `replace`, `move`, `copy` or `test`.", + "x-intellij-html-description": "operation carried by the patch: add, remove, replace, move, copy or test.", + "default": "replace" + }, + "path": { + "type": "string", + "description": "position in the yaml where the operation takes place. For example, this targets the `dockerfile` of the first artifact built.", + "x-intellij-html-description": "position in the yaml where the operation takes place. For example, this targets the dockerfile of the first artifact built.", + "examples": [ + "/build/artifacts/0/docker/dockerfile" + ] + }, + "value": { + "type": "object", + "description": "value to apply. Can be any portion of yaml.", + "x-intellij-html-description": "value to apply. Can be any portion of yaml." + } + }, + "preferredOrder": [ + "op", + "path", + "from", + "value" + ], + "additionalProperties": false, + "description": "patch to be applied by a profile.", + "x-intellij-html-description": "patch to be applied by a profile." + }, + "JibGradleArtifact": { + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array", + "description": "additional build flags passed to Gradle.", + "x-intellij-html-description": "additional build flags passed to Gradle.", + "default": "[]", + "examples": [ + "[\"--no-build-cache\"]" + ] + }, + "project": { + "type": "string", + "description": "selects which Gradle project to build.", + "x-intellij-html-description": "selects which Gradle project to build." + } + }, + "preferredOrder": [ + "project", + "args" + ], + "additionalProperties": false, + "description": "*alpha* builds images using the [Jib plugin for Gradle](https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin).", + "x-intellij-html-description": "alpha builds images using the Jib plugin for Gradle." + }, + "JibMavenArtifact": { + "properties": { + "args": { + "items": { + "type": "string" + }, + "type": "array", + "description": "additional build flags passed to Maven.", + "x-intellij-html-description": "additional build flags passed to Maven.", + "default": "[]", + "examples": [ + "[\"-x\", \"-DskipTests\"]" + ] + }, + "module": { + "type": "string", + "description": "selects which Maven module to build, for a multi module project.", + "x-intellij-html-description": "selects which Maven module to build, for a multi module project." + }, + "profile": { + "type": "string", + "description": "selects which Maven profile to activate.", + "x-intellij-html-description": "selects which Maven profile to activate." + } + }, + "preferredOrder": [ + "module", + "profile", + "args" + ], + "additionalProperties": false, + "description": "*alpha* builds images using the [Jib plugin for Maven](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin).", + "x-intellij-html-description": "alpha builds images using the Jib plugin for Maven." + }, + "KanikoArtifact": { + "properties": { + "buildArgs": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "description": "arguments passed to the docker build. It also accepts environment variables via the go template syntax.", + "x-intellij-html-description": "arguments passed to the docker build. It also accepts environment variables via the go template syntax.", + "default": "{}", + "examples": [ + "{\"key1\": \"value1\", \"key2\": \"value2\", \"key3\": \"{{.ENV_VARIABLE}}\"}" + ] + }, + "buildContext": { + "$ref": "#/definitions/KanikoBuildContext", + "description": "where the build context for this artifact resides.", + "x-intellij-html-description": "where the build context for this artifact resides." + }, + "cache": { + "$ref": "#/definitions/KanikoCache", + "description": "configures Kaniko caching. If a cache is specified, Kaniko will use a remote cache which will speed up builds.", + "x-intellij-html-description": "configures Kaniko caching. If a cache is specified, Kaniko will use a remote cache which will speed up builds." + }, + "dockerfile": { + "type": "string", + "description": "locates the Dockerfile relative to workspace.", + "x-intellij-html-description": "locates the Dockerfile relative to workspace.", + "default": "Dockerfile" + }, + "flags": { + "items": { + "type": "string" + }, + "type": "array", + "description": "additional flags to be passed to Kaniko command line. See [Kaniko Additional Flags](https://github.com/GoogleContainerTools/kaniko#additional-flags). Deprecated - instead the named, unique fields should be used, e.g. `buildArgs`, `cache`, `target`.", + "x-intellij-html-description": "additional flags to be passed to Kaniko command line. See Kaniko Additional Flags. Deprecated - instead the named, unique fields should be used, e.g. buildArgs, cache, target.", + "default": "[]" + }, + "image": { + "type": "string", + "description": "Docker image used by the Kaniko pod. Defaults to the latest released version of `gcr.io/kaniko-project/executor`.", + "x-intellij-html-description": "Docker image used by the Kaniko pod. Defaults to the latest released version of gcr.io/kaniko-project/executor." + }, + "reproducible": { + "type": "boolean", + "description": "used to strip timestamps out of the built image.", + "x-intellij-html-description": "used to strip timestamps out of the built image.", + "default": "false" + }, + "target": { + "type": "string", + "description": "Dockerfile target name to build.", + "x-intellij-html-description": "Dockerfile target name to build." + } + }, + "preferredOrder": [ + "flags", + "dockerfile", + "target", + "buildArgs", + "buildContext", + "image", + "cache", + "reproducible" + ], + "additionalProperties": false, + "description": "*alpha* describes an artifact built from a Dockerfile, with kaniko.", + "x-intellij-html-description": "alpha describes an artifact built from a Dockerfile, with kaniko." + }, + "KanikoBuildContext": { + "properties": { + "gcsBucket": { + "type": "string", + "description": "GCS bucket to which sources are uploaded. Kaniko will need access to that bucket to download the sources.", + "x-intellij-html-description": "GCS bucket to which sources are uploaded. Kaniko will need access to that bucket to download the sources." + }, + "localDir": { + "$ref": "#/definitions/LocalDir", + "description": "configures how Kaniko mounts sources directly via an `emptyDir` volume.", + "x-intellij-html-description": "configures how Kaniko mounts sources directly via an emptyDir volume." + } + }, + "preferredOrder": [ + "gcsBucket", + "localDir" + ], + "additionalProperties": false, + "description": "contains the different fields available to specify a Kaniko build context.", + "x-intellij-html-description": "contains the different fields available to specify a Kaniko build context." + }, + "KanikoCache": { + "properties": { + "hostPath": { + "type": "string", + "description": "specifies a path on the host that is mounted to each pod as read only cache volume containing base images. If set, must exist on each node and prepopulated with kaniko-warmer.", + "x-intellij-html-description": "specifies a path on the host that is mounted to each pod as read only cache volume containing base images. If set, must exist on each node and prepopulated with kaniko-warmer." + }, + "repo": { + "type": "string", + "description": "a remote repository to store cached layers. If none is specified, one will be inferred from the image name. See [Kaniko Caching](https://github.com/GoogleContainerTools/kaniko#caching).", + "x-intellij-html-description": "a remote repository to store cached layers. If none is specified, one will be inferred from the image name. See Kaniko Caching." + } + }, + "preferredOrder": [ + "repo", + "hostPath" + ], + "additionalProperties": false, + "description": "configures Kaniko caching. If a cache is specified, Kaniko will use a remote cache which will speed up builds.", + "x-intellij-html-description": "configures Kaniko caching. If a cache is specified, Kaniko will use a remote cache which will speed up builds." + }, + "KubectlDeploy": { + "properties": { + "flags": { + "$ref": "#/definitions/KubectlFlags", + "description": "additional flags passed to `kubectl`.", + "x-intellij-html-description": "additional flags passed to kubectl." + }, + "manifests": { + "items": { + "type": "string" + }, + "type": "array", + "description": "the Kubernetes yaml or json manifests.", + "x-intellij-html-description": "the Kubernetes yaml or json manifests.", + "default": "[\"k8s/*.yaml\"]" + }, + "remoteManifests": { + "items": { + "type": "string" + }, + "type": "array", + "description": "Kubernetes manifests in remote clusters.", + "x-intellij-html-description": "Kubernetes manifests in remote clusters.", + "default": "[]" + } + }, + "preferredOrder": [ + "manifests", + "remoteManifests", + "flags" + ], + "additionalProperties": false, + "description": "*beta* uses a client side `kubectl apply` to deploy manifests. You'll need a `kubectl` CLI version installed that's compatible with your cluster.", + "x-intellij-html-description": "beta uses a client side kubectl apply to deploy manifests. You'll need a kubectl CLI version installed that's compatible with your cluster." + }, + "KubectlFlags": { + "properties": { + "apply": { + "items": { + "type": "string" + }, + "type": "array", + "description": "additional flags passed on creations (`kubectl apply`).", + "x-intellij-html-description": "additional flags passed on creations (kubectl apply).", + "default": "[]" + }, + "delete": { + "items": { + "type": "string" + }, + "type": "array", + "description": "additional flags passed on deletions (`kubectl delete`).", + "x-intellij-html-description": "additional flags passed on deletions (kubectl delete).", + "default": "[]" + }, + "global": { + "items": { + "type": "string" + }, + "type": "array", + "description": "additional flags passed on every command.", + "x-intellij-html-description": "additional flags passed on every command.", + "default": "[]" + } + }, + "preferredOrder": [ + "global", + "apply", + "delete" + ], + "additionalProperties": false, + "description": "additional flags passed on the command line to kubectl either on every command (Global), on creations (Apply) or deletions (Delete).", + "x-intellij-html-description": "additional flags passed on the command line to kubectl either on every command (Global), on creations (Apply) or deletions (Delete)." + }, + "KustomizeDeploy": { + "properties": { + "flags": { + "$ref": "#/definitions/KubectlFlags", + "description": "additional flags passed to `kubectl`.", + "x-intellij-html-description": "additional flags passed to kubectl." + }, + "path": { + "type": "string", + "description": "path to Kustomization files.", + "x-intellij-html-description": "path to Kustomization files.", + "default": "." + } + }, + "preferredOrder": [ + "path", + "flags" + ], + "additionalProperties": false, + "description": "*beta* uses the `kustomize` CLI to \"patch\" a deployment for a target environment.", + "x-intellij-html-description": "beta uses the kustomize CLI to "patch" a deployment for a target environment." + }, + "LocalBuild": { + "properties": { + "push": { + "type": "boolean", + "description": "should images be pushed to a registry. If not specified, images are pushed only if the current Kubernetes context connects to a remote cluster.", + "x-intellij-html-description": "should images be pushed to a registry. If not specified, images are pushed only if the current Kubernetes context connects to a remote cluster." + }, + "useBuildkit": { + "type": "boolean", + "description": "use BuildKit to build Docker images.", + "x-intellij-html-description": "use BuildKit to build Docker images.", + "default": "false" + }, + "useDockerCLI": { + "type": "boolean", + "description": "use `docker` command-line interface instead of Docker Engine APIs.", + "x-intellij-html-description": "use docker command-line interface instead of Docker Engine APIs.", + "default": "false" + } + }, + "preferredOrder": [ + "push", + "useDockerCLI", + "useBuildkit" + ], + "additionalProperties": false, + "description": "*beta* describes how to do a build on the local docker daemon and optionally push to a repository.", + "x-intellij-html-description": "beta describes how to do a build on the local docker daemon and optionally push to a repository." + }, + "LocalDir": { + "properties": { + "initImage": { + "type": "string", + "description": "image used to run init container which mounts kaniko context.", + "x-intellij-html-description": "image used to run init container which mounts kaniko context." + } + }, + "preferredOrder": [ + "initImage" + ], + "additionalProperties": false, + "description": "configures how Kaniko mounts sources directly via an `emptyDir` volume.", + "x-intellij-html-description": "configures how Kaniko mounts sources directly via an emptyDir volume." + }, + "Metadata": { + "properties": { + "name": { + "type": "string", + "description": "an identifier for the project.", + "x-intellij-html-description": "an identifier for the project." + } + }, + "preferredOrder": [ + "name" + ], + "additionalProperties": false, + "description": "holds an optional name of the project.", + "x-intellij-html-description": "holds an optional name of the project." + }, + "PortForwardResource": { + "properties": { + "localPort": { + "type": "integer", + "description": "local port to forward to. If the port is unavailable, Skaffold will choose a random open port to forward to. *Optional*.", + "x-intellij-html-description": "local port to forward to. If the port is unavailable, Skaffold will choose a random open port to forward to. Optional." + }, + "namespace": { + "type": "string", + "description": "namespace of the resource to port forward.", + "x-intellij-html-description": "namespace of the resource to port forward." + }, + "port": { + "type": "integer", + "description": "resource port that will be forwarded.", + "x-intellij-html-description": "resource port that will be forwarded." + }, + "resourceName": { + "type": "string", + "description": "name of the Kubernetes resource to port forward.", + "x-intellij-html-description": "name of the Kubernetes resource to port forward." + }, + "resourceType": { + "$ref": "#/definitions/ResourceType", + "description": "Kubernetes type that should be port forwarded. Acceptable resource types include: `Service`, `Pod` and Controller resource type that has a pod spec: `ReplicaSet`, `ReplicationController`, `Deployment`, `StatefulSet`, `DaemonSet`, `Job`, `CronJob`.", + "x-intellij-html-description": "Kubernetes type that should be port forwarded. Acceptable resource types include: Service, Pod and Controller resource type that has a pod spec: ReplicaSet, ReplicationController, Deployment, StatefulSet, DaemonSet, Job, CronJob." + } + }, + "preferredOrder": [ + "resourceType", + "resourceName", + "namespace", + "port", + "localPort" + ], + "additionalProperties": false, + "description": "describes a resource to port forward.", + "x-intellij-html-description": "describes a resource to port forward." + }, + "Profile": { + "required": [ + "name" + ], + "properties": { + "activation": { + "items": { + "$ref": "#/definitions/Activation" + }, + "type": "array", + "description": "criteria by which a profile can be auto-activated. The profile is auto-activated if any one of the activations are triggered. An activation is triggered if all of the criteria (env, kubeContext, command) are triggered.", + "x-intellij-html-description": "criteria by which a profile can be auto-activated. The profile is auto-activated if any one of the activations are triggered. An activation is triggered if all of the criteria (env, kubeContext, command) are triggered." + }, + "build": { + "$ref": "#/definitions/BuildConfig", + "description": "describes how images are built.", + "x-intellij-html-description": "describes how images are built." + }, + "deploy": { + "$ref": "#/definitions/DeployConfig", + "description": "describes how images are deployed.", + "x-intellij-html-description": "describes how images are deployed." + }, + "name": { + "type": "string", + "description": "a unique profile name.", + "x-intellij-html-description": "a unique profile name.", + "examples": [ + "profile-prod" + ] + }, + "patches": { + "items": { + "$ref": "#/definitions/JSONPatch" + }, + "type": "array", + "description": "patches applied to the configuration. Patches use the JSON patch notation.", + "x-intellij-html-description": "patches applied to the configuration. Patches use the JSON patch notation." + }, + "portForward": { + "items": { + "$ref": "#/definitions/PortForwardResource" + }, + "type": "array", + "description": "describes user defined resources to port-forward.", + "x-intellij-html-description": "describes user defined resources to port-forward." + }, + "test": { + "items": { + "$ref": "#/definitions/TestCase" + }, + "type": "array", + "description": "describes how images are tested.", + "x-intellij-html-description": "describes how images are tested." + } + }, + "preferredOrder": [ + "name", + "build", + "test", + "deploy", + "portForward", + "patches", + "activation" + ], + "additionalProperties": false, + "description": "*beta* profiles are used to override any `build`, `test` or `deploy` configuration.", + "x-intellij-html-description": "beta profiles are used to override any build, test or deploy configuration." + }, + "ResourceRequirement": { + "properties": { + "cpu": { + "type": "string", + "description": "the number cores to be used.", + "x-intellij-html-description": "the number cores to be used.", + "examples": [ + "2`, `2.0` or `200m" + ] + }, + "memory": { + "type": "string", + "description": "the amount of memory to allocate to the pod.", + "x-intellij-html-description": "the amount of memory to allocate to the pod.", + "examples": [ + "1Gi` or `1000Mi" + ] + } + }, + "preferredOrder": [ + "cpu", + "memory" + ], + "additionalProperties": false, + "description": "stores the CPU/Memory requirements for the pod.", + "x-intellij-html-description": "stores the CPU/Memory requirements for the pod." + }, + "ResourceRequirements": { + "properties": { + "limits": { + "$ref": "#/definitions/ResourceRequirement", + "description": "[resource limits](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#resource-requests-and-limits-of-pod-and-container) for the Kaniko pod.", + "x-intellij-html-description": "resource limits for the Kaniko pod." + }, + "requests": { + "$ref": "#/definitions/ResourceRequirement", + "description": "[resource requests](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#resource-requests-and-limits-of-pod-and-container) for the Kaniko pod.", + "x-intellij-html-description": "resource requests for the Kaniko pod." + } + }, + "preferredOrder": [ + "requests", + "limits" + ], + "additionalProperties": false, + "description": "describes the resource requirements for the kaniko pod.", + "x-intellij-html-description": "describes the resource requirements for the kaniko pod." + }, + "ResourceType": { + "type": "string", + "description": "describes the Kubernetes resource types used for port forwarding.", + "x-intellij-html-description": "describes the Kubernetes resource types used for port forwarding." + }, + "ShaTagger": { + "description": "*beta* tags images with their sha256 digest.", + "x-intellij-html-description": "beta tags images with their sha256 digest." + }, + "SkaffoldConfig": { + "required": [ + "apiVersion", + "kind" + ], + "properties": { + "apiVersion": { + "type": "string", + "description": "version of the configuration.", + "x-intellij-html-description": "version of the configuration." + }, + "build": { + "$ref": "#/definitions/BuildConfig", + "description": "describes how images are built.", + "x-intellij-html-description": "describes how images are built." + }, + "deploy": { + "$ref": "#/definitions/DeployConfig", + "description": "describes how images are deployed.", + "x-intellij-html-description": "describes how images are deployed." + }, + "kind": { + "type": "string", + "description": "always `Config`.", + "x-intellij-html-description": "always Config.", + "default": "Config" + }, + "metadata": { + "$ref": "#/definitions/Metadata", + "description": "holds additional information about the config.", + "x-intellij-html-description": "holds additional information about the config." + }, + "portForward": { + "items": { + "$ref": "#/definitions/PortForwardResource" + }, + "type": "array", + "description": "describes user defined resources to port-forward.", + "x-intellij-html-description": "describes user defined resources to port-forward." + }, + "profiles": { + "items": { + "$ref": "#/definitions/Profile" + }, + "type": "array", + "description": "*beta* can override be used to `build`, `test` or `deploy` configuration.", + "x-intellij-html-description": "beta can override be used to build, test or deploy configuration." + }, + "test": { + "items": { + "$ref": "#/definitions/TestCase" + }, + "type": "array", + "description": "describes how images are tested.", + "x-intellij-html-description": "describes how images are tested." + } + }, + "preferredOrder": [ + "apiVersion", + "kind", + "metadata", + "build", + "test", + "deploy", + "portForward", + "profiles" + ], + "additionalProperties": false, + "description": "holds the fields parsed from the Skaffold configuration file (skaffold.yaml).", + "x-intellij-html-description": "holds the fields parsed from the Skaffold configuration file (skaffold.yaml)." + }, + "Sync": { + "properties": { + "infer": { + "items": { + "type": "string" + }, + "type": "array", + "description": "file patterns which may be synced into the container. The container destination is inferred by the builder. Currently only available for docker artifacts.", + "x-intellij-html-description": "file patterns which may be synced into the container. The container destination is inferred by the builder. Currently only available for docker artifacts.", + "default": "[]" + }, + "manual": { + "items": { + "$ref": "#/definitions/SyncRule" + }, + "type": "array", + "description": "manual sync rules indicating the source and destination.", + "x-intellij-html-description": "manual sync rules indicating the source and destination." + } + }, + "preferredOrder": [ + "manual", + "infer" + ], + "additionalProperties": false, + "description": "*alpha* specifies what files to sync into the container. This is a list of sync rules indicating the intent to sync for source files.", + "x-intellij-html-description": "alpha specifies what files to sync into the container. This is a list of sync rules indicating the intent to sync for source files." + }, + "SyncRule": { + "required": [ + "src", + "dest" + ], + "properties": { + "dest": { + "type": "string", + "description": "destination path in the container where the files should be synced to.", + "x-intellij-html-description": "destination path in the container where the files should be synced to.", + "examples": [ + "\"app/\"" + ] + }, + "src": { + "type": "string", + "description": "a glob pattern to match local paths against. Directories should be delimited by `/` on all platforms.", + "x-intellij-html-description": "a glob pattern to match local paths against. Directories should be delimited by / on all platforms.", + "examples": [ + "\"css/**/*.css\"" + ] + }, + "strip": { + "type": "string", + "description": "specifies the path prefix to remove from the source path when transplanting the files into the destination folder.", + "x-intellij-html-description": "specifies the path prefix to remove from the source path when transplanting the files into the destination folder.", + "examples": [ + "\"css/\"" + ] + } + }, + "preferredOrder": [ + "src", + "dest", + "strip" + ], + "additionalProperties": false, + "description": "specifies which local files to sync to remote folders.", + "x-intellij-html-description": "specifies which local files to sync to remote folders." + }, + "TagPolicy": { + "properties": { + "dateTime": { + "$ref": "#/definitions/DateTimeTagger", + "description": "*beta* tags images with the build timestamp.", + "x-intellij-html-description": "beta tags images with the build timestamp." + }, + "envTemplate": { + "$ref": "#/definitions/EnvTemplateTagger", + "description": "*beta* tags images with a configurable template string.", + "x-intellij-html-description": "beta tags images with a configurable template string." + }, + "gitCommit": { + "$ref": "#/definitions/GitTagger", + "description": "*beta* tags images with the git tag or commit of the artifact's workspace.", + "x-intellij-html-description": "beta tags images with the git tag or commit of the artifact's workspace." + }, + "sha256": { + "$ref": "#/definitions/ShaTagger", + "description": "*beta* tags images with their sha256 digest.", + "x-intellij-html-description": "beta tags images with their sha256 digest." + } + }, + "preferredOrder": [ + "gitCommit", + "sha256", + "envTemplate", + "dateTime" + ], + "additionalProperties": false, + "description": "contains all the configuration for the tagging step.", + "x-intellij-html-description": "contains all the configuration for the tagging step." + }, + "TestCase": { + "required": [ + "image" + ], + "properties": { + "image": { + "type": "string", + "description": "artifact on which to run those tests.", + "x-intellij-html-description": "artifact on which to run those tests.", + "examples": [ + "gcr.io/k8s-skaffold/example" + ] + }, + "structureTests": { + "items": { + "type": "string" + }, + "type": "array", + "description": "the [Container Structure Tests](https://github.com/GoogleContainerTools/container-structure-test) to run on that artifact.", + "x-intellij-html-description": "the Container Structure Tests to run on that artifact.", + "default": "[]", + "examples": [ + "[\"./test/*\"]" + ] + } + }, + "preferredOrder": [ + "image", + "structureTests" + ], + "additionalProperties": false, + "description": "a list of structure tests to run on images that Skaffold builds.", + "x-intellij-html-description": "a list of structure tests to run on images that Skaffold builds." + } + } +} diff --git a/hack/new_version.sh b/hack/new_version.sh index 16d02791d64..115e78df26b 100755 --- a/hack/new_version.sh +++ b/hack/new_version.sh @@ -14,6 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +echo "Current skaffold config version: " $(sed -n 's;.*Version.*"skaffold/\(.*\)";\1;p' pkg/skaffold/schema/latest/config.go) + +echo echo "Please enter new config version:" read NEW_VERSION diff --git a/integration/examples/bazel/skaffold.yaml b/integration/examples/bazel/skaffold.yaml index ef6b3b5b28a..05ce33d0f9f 100644 --- a/integration/examples/bazel/skaffold.yaml +++ b/integration/examples/bazel/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/examples/getting-started/skaffold.yaml b/integration/examples/getting-started/skaffold.yaml index b98ebe9d6e1..0c6eeaed16d 100644 --- a/integration/examples/getting-started/skaffold.yaml +++ b/integration/examples/getting-started/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/examples/google-cloud-build/skaffold.yaml b/integration/examples/google-cloud-build/skaffold.yaml index aa5fe57784f..0f13a8bf1ee 100644 --- a/integration/examples/google-cloud-build/skaffold.yaml +++ b/integration/examples/google-cloud-build/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: googleCloudBuild: diff --git a/integration/examples/helm-deployment-dependencies/skaffold.yaml b/integration/examples/helm-deployment-dependencies/skaffold.yaml index 8b806f35653..3b77eaf55af 100644 --- a/integration/examples/helm-deployment-dependencies/skaffold.yaml +++ b/integration/examples/helm-deployment-dependencies/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: tagPolicy: diff --git a/integration/examples/helm-deployment/skaffold.yaml b/integration/examples/helm-deployment/skaffold.yaml index 431e939060a..e0108781478 100644 --- a/integration/examples/helm-deployment/skaffold.yaml +++ b/integration/examples/helm-deployment/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: tagPolicy: diff --git a/integration/examples/hot-reload/skaffold.yaml b/integration/examples/hot-reload/skaffold.yaml index 61d714ab9f2..0e7d0c41067 100644 --- a/integration/examples/hot-reload/skaffold.yaml +++ b/integration/examples/hot-reload/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/examples/jib-gradle/skaffold.yaml b/integration/examples/jib-gradle/skaffold.yaml index e0335077904..51253318cd1 100644 --- a/integration/examples/jib-gradle/skaffold.yaml +++ b/integration/examples/jib-gradle/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/examples/jib-multimodule/skaffold.yaml b/integration/examples/jib-multimodule/skaffold.yaml index 6d3ee648370..de437207070 100644 --- a/integration/examples/jib-multimodule/skaffold.yaml +++ b/integration/examples/jib-multimodule/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/examples/jib/skaffold.yaml b/integration/examples/jib/skaffold.yaml index a8c68b8cff5..82f603cee09 100644 --- a/integration/examples/jib/skaffold.yaml +++ b/integration/examples/jib/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/examples/kaniko-local/skaffold.yaml b/integration/examples/kaniko-local/skaffold.yaml index 2281ecef910..78c3099d375 100644 --- a/integration/examples/kaniko-local/skaffold.yaml +++ b/integration/examples/kaniko-local/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/examples/kaniko/skaffold.yaml b/integration/examples/kaniko/skaffold.yaml index 810aa9b454d..5979d2ed478 100644 --- a/integration/examples/kaniko/skaffold.yaml +++ b/integration/examples/kaniko/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/examples/kustomize/skaffold.yaml b/integration/examples/kustomize/skaffold.yaml index 76607ec33cb..8993e84ff81 100644 --- a/integration/examples/kustomize/skaffold.yaml +++ b/integration/examples/kustomize/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config deploy: kustomize: {} diff --git a/integration/examples/microservices/skaffold.yaml b/integration/examples/microservices/skaffold.yaml index bdf0fcb520c..e9e1a30c921 100644 --- a/integration/examples/microservices/skaffold.yaml +++ b/integration/examples/microservices/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/examples/nodejs/skaffold.yaml b/integration/examples/nodejs/skaffold.yaml index 606306520f0..2c761aa7bd6 100644 --- a/integration/examples/nodejs/skaffold.yaml +++ b/integration/examples/nodejs/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/examples/react-reload/skaffold.yaml b/integration/examples/react-reload/skaffold.yaml index 8b3dd53d3e6..d929d264b39 100644 --- a/integration/examples/react-reload/skaffold.yaml +++ b/integration/examples/react-reload/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/examples/structure-tests/skaffold.yaml b/integration/examples/structure-tests/skaffold.yaml index 7643f98be00..e836f9ed4bf 100644 --- a/integration/examples/structure-tests/skaffold.yaml +++ b/integration/examples/structure-tests/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/examples/tagging-with-environment-variables/skaffold.yaml b/integration/examples/tagging-with-environment-variables/skaffold.yaml index a2cf3058cfd..1e1d7b9fb40 100644 --- a/integration/examples/tagging-with-environment-variables/skaffold.yaml +++ b/integration/examples/tagging-with-environment-variables/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/testdata/build/skaffold.yaml b/integration/testdata/build/skaffold.yaml index a15ef4abccb..63fd6cc5424 100644 --- a/integration/testdata/build/skaffold.yaml +++ b/integration/testdata/build/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: local: diff --git a/integration/testdata/custom/skaffold.yaml b/integration/testdata/custom/skaffold.yaml index eae53603e0c..d2099e279eb 100644 --- a/integration/testdata/custom/skaffold.yaml +++ b/integration/testdata/custom/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/testdata/dev/skaffold.yaml b/integration/testdata/dev/skaffold.yaml index b75f781e4f6..505b14a3ec4 100644 --- a/integration/testdata/dev/skaffold.yaml +++ b/integration/testdata/dev/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/testdata/gke_loadbalancer/skaffold.yaml b/integration/testdata/gke_loadbalancer/skaffold.yaml index ba1d0f37efe..5f2287b6a5e 100644 --- a/integration/testdata/gke_loadbalancer/skaffold.yaml +++ b/integration/testdata/gke_loadbalancer/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/testdata/jib-gradle/skaffold.yaml b/integration/testdata/jib-gradle/skaffold.yaml index 993a3ea4d5d..034798a8091 100644 --- a/integration/testdata/jib-gradle/skaffold.yaml +++ b/integration/testdata/jib-gradle/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/testdata/jib/skaffold.yaml b/integration/testdata/jib/skaffold.yaml index 2464a19bfe5..b2ac251cdda 100644 --- a/integration/testdata/jib/skaffold.yaml +++ b/integration/testdata/jib/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/testdata/kaniko-microservices/skaffold.yaml b/integration/testdata/kaniko-microservices/skaffold.yaml index 7acc19f08db..83f1ae31656 100644 --- a/integration/testdata/kaniko-microservices/skaffold.yaml +++ b/integration/testdata/kaniko-microservices/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/testdata/kaniko-sub-folder/skaffold.yaml b/integration/testdata/kaniko-sub-folder/skaffold.yaml index baac0705c7b..ccfb6a3f5c8 100644 --- a/integration/testdata/kaniko-sub-folder/skaffold.yaml +++ b/integration/testdata/kaniko-sub-folder/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/testdata/kaniko-target/skaffold.yaml b/integration/testdata/kaniko-target/skaffold.yaml index e273b412c7f..31c64888ab7 100644 --- a/integration/testdata/kaniko-target/skaffold.yaml +++ b/integration/testdata/kaniko-target/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/integration/testdata/tagPolicy/skaffold.yaml b/integration/testdata/tagPolicy/skaffold.yaml index 4fcd0f1d2f3..2a8372905af 100644 --- a/integration/testdata/tagPolicy/skaffold.yaml +++ b/integration/testdata/tagPolicy/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1beta13 +apiVersion: skaffold/v1beta14 kind: Config build: artifacts: diff --git a/pkg/skaffold/schema/latest/config.go b/pkg/skaffold/schema/latest/config.go index 4b132fb548c..b3a69a54d3b 100644 --- a/pkg/skaffold/schema/latest/config.go +++ b/pkg/skaffold/schema/latest/config.go @@ -20,7 +20,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/util" ) -const Version string = "skaffold/v1beta13" +const Version string = "skaffold/v1beta14" // NewSkaffoldConfig creates a SkaffoldConfig func NewSkaffoldConfig() util.VersionedConfig { diff --git a/pkg/skaffold/schema/v1beta10/upgrade.go b/pkg/skaffold/schema/v1beta10/upgrade.go index 49f29d87cea..62f893da957 100644 --- a/pkg/skaffold/schema/v1beta10/upgrade.go +++ b/pkg/skaffold/schema/v1beta10/upgrade.go @@ -23,7 +23,7 @@ import ( ) // Upgrade upgrades a configuration to the next version. -// Config changes from v1beta9 to v1beta10 +// Config changes from v1beta10 to v1beta11 // 1. Additions: // - GitTagger variants `TreeSha` and `AbbrevTreeSha` // 2. No removals diff --git a/pkg/skaffold/schema/v1beta11/upgrade.go b/pkg/skaffold/schema/v1beta11/upgrade.go index 607f7014361..f439470c8e9 100644 --- a/pkg/skaffold/schema/v1beta11/upgrade.go +++ b/pkg/skaffold/schema/v1beta11/upgrade.go @@ -23,7 +23,7 @@ import ( ) // Upgrade upgrades a configuration to the next version. -// Config changes from v1beta9 to v1beta10 +// Config changes from v1beta11 to v1beta12 // 1. No Additions // 2. No removals // 3. No Updates diff --git a/pkg/skaffold/schema/v1beta12/upgrade.go b/pkg/skaffold/schema/v1beta12/upgrade.go index 30db5cc6958..457d94e9a33 100755 --- a/pkg/skaffold/schema/v1beta12/upgrade.go +++ b/pkg/skaffold/schema/v1beta12/upgrade.go @@ -17,13 +17,13 @@ limitations under the License. package v1beta12 import ( - next "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/util" + next "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1beta13" pkgutil "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" ) // Upgrade upgrades a configuration to the next version. -// Config changes from v1beta9 to v1beta10 +// Config changes from v1beta12 to v1beta13 // 1. No Additions // 2. No removals // 3. No Updates diff --git a/pkg/skaffold/schema/v1beta12/upgrade_test.go b/pkg/skaffold/schema/v1beta12/upgrade_test.go index 2bf81c45024..f772925c031 100755 --- a/pkg/skaffold/schema/v1beta12/upgrade_test.go +++ b/pkg/skaffold/schema/v1beta12/upgrade_test.go @@ -19,7 +19,7 @@ package v1beta12 import ( "testing" - next "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" + next "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1beta13" "github.com/GoogleContainerTools/skaffold/testutil" yaml "gopkg.in/yaml.v2" ) diff --git a/pkg/skaffold/schema/v1beta13/config.go b/pkg/skaffold/schema/v1beta13/config.go new file mode 100755 index 00000000000..5cf08646c11 --- /dev/null +++ b/pkg/skaffold/schema/v1beta13/config.go @@ -0,0 +1,772 @@ +/* +Copyright 2019 The Skaffold 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 v1beta13 + +import ( + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/util" +) + +const Version string = "skaffold/v1beta13" + +// NewSkaffoldConfig creates a SkaffoldConfig +func NewSkaffoldConfig() util.VersionedConfig { + return new(SkaffoldConfig) +} + +// SkaffoldConfig holds the fields parsed from the Skaffold configuration file (skaffold.yaml). +type SkaffoldConfig struct { + // APIVersion is the version of the configuration. + APIVersion string `yaml:"apiVersion" yamltags:"required"` + + // Kind is always `Config`. Defaults to `Config`. + Kind string `yaml:"kind" yamltags:"required"` + + // Metadata holds additional information about the config. + Metadata Metadata `yaml:"metadata,omitempty"` + + // Pipeline defines the Build/Test/Deploy phases. + Pipeline `yaml:",inline"` + + // Profiles *beta* can override be used to `build`, `test` or `deploy` configuration. + Profiles []Profile `yaml:"profiles,omitempty"` +} + +// Metadata holds an optional name of the project. +type Metadata struct { + // Name is an identifier for the project. + Name string `yaml:"name,omitempty"` +} + +// Pipeline describes a Skaffold pipeline. +type Pipeline struct { + // Build describes how images are built. + Build BuildConfig `yaml:"build,omitempty"` + + // Test describes how images are tested. + Test []*TestCase `yaml:"test,omitempty"` + + // Deploy describes how images are deployed. + Deploy DeployConfig `yaml:"deploy,omitempty"` + + // PortForward describes user defined resources to port-forward. + PortForward []*PortForwardResource `yaml:"portForward,omitempty"` +} + +func (c *SkaffoldConfig) GetVersion() string { + return c.APIVersion +} + +// ResourceType describes the Kubernetes resource types used for port forwarding. +type ResourceType string + +// PortForwardResource describes a resource to port forward. +type PortForwardResource struct { + // Type is the Kubernetes type that should be port forwarded. + // Acceptable resource types include: `Service`, `Pod` and Controller resource type that has a pod spec: `ReplicaSet`, `ReplicationController`, `Deployment`, `StatefulSet`, `DaemonSet`, `Job`, `CronJob`. + Type ResourceType `yaml:"resourceType,omitempty"` + + // Name is the name of the Kubernetes resource to port forward. + Name string `yaml:"resourceName,omitempty"` + + // Namespace is the namespace of the resource to port forward. + Namespace string `yaml:"namespace,omitempty"` + + // Port is the resource port that will be forwarded. + Port int `yaml:"port,omitempty"` + + // LocalPort is the local port to forward to. If the port is unavailable, Skaffold will choose a random open port to forward to. *Optional*. + LocalPort int `yaml:"localPort,omitempty"` +} + +// BuildConfig contains all the configuration for the build steps. +type BuildConfig struct { + // Artifacts lists the images you're going to be building. + Artifacts []*Artifact `yaml:"artifacts,omitempty"` + + // InsecureRegistries is a list of registries declared by the user to be insecure. + // These registries will be connected to via HTTP instead of HTTPS. + InsecureRegistries []string `yaml:"insecureRegistries,omitempty"` + + // TagPolicy *beta* determines how images are tagged. + // A few strategies are provided here, although you most likely won't need to care! + // If not specified, it defaults to `gitCommit: {variant: Tags}`. + TagPolicy TagPolicy `yaml:"tagPolicy,omitempty"` + + BuildType `yaml:",inline"` +} + +// TagPolicy contains all the configuration for the tagging step. +type TagPolicy struct { + // GitTagger *beta* tags images with the git tag or commit of the artifact's workspace. + GitTagger *GitTagger `yaml:"gitCommit,omitempty" yamltags:"oneOf=tag"` + + // ShaTagger *beta* tags images with their sha256 digest. + ShaTagger *ShaTagger `yaml:"sha256,omitempty" yamltags:"oneOf=tag"` + + // EnvTemplateTagger *beta* tags images with a configurable template string. + EnvTemplateTagger *EnvTemplateTagger `yaml:"envTemplate,omitempty" yamltags:"oneOf=tag"` + + // DateTimeTagger *beta* tags images with the build timestamp. + DateTimeTagger *DateTimeTagger `yaml:"dateTime,omitempty" yamltags:"oneOf=tag"` +} + +// ShaTagger *beta* tags images with their sha256 digest. +type ShaTagger struct{} + +// GitTagger *beta* tags images with the git tag or commit of the artifact's workspace. +type GitTagger struct { + // Variant determines the behavior of the git tagger. Valid variants are + // `Tags` (default): use git tags or fall back to abbreviated commit hash. + // `CommitSha`: use the full git commit sha. + // `AbbrevCommitSha`: use the abbreviated git commit sha. + // `TreeSha`: use the full tree hash of the artifact workingdir. + // `AbbrevTreeSha`: use the abbreviated tree hash of the artifact workingdir. + Variant string `yaml:"variant,omitempty"` +} + +// EnvTemplateTagger *beta* tags images with a configurable template string. +type EnvTemplateTagger struct { + // Template used to produce the image name and tag. + // See golang [text/template](https://golang.org/pkg/text/template/). + // The template is executed against the current environment, + // with those variables injected: + // IMAGE_NAME | Name of the image being built, as supplied in the artifacts section. + // For example: `{{.RELEASE}}-{{.IMAGE_NAME}}`. + Template string `yaml:"template,omitempty" yamltags:"required"` +} + +// DateTimeTagger *beta* tags images with the build timestamp. +type DateTimeTagger struct { + // Format formats the date and time. + // See [#Time.Format](https://golang.org/pkg/time/#Time.Format). + // Defaults to `2006-01-02_15-04-05.999_MST`. + Format string `yaml:"format,omitempty"` + + // TimeZone sets the timezone for the date and time. + // See [Time.LoadLocation](https://golang.org/pkg/time/#Time.LoadLocation). + // Defaults to the local timezone. + TimeZone string `yaml:"timezone,omitempty"` +} + +// BuildType contains the specific implementation and parameters needed +// for the build step. Only one field should be populated. +type BuildType struct { + // LocalBuild *beta* describes how to do a build on the local docker daemon + // and optionally push to a repository. + LocalBuild *LocalBuild `yaml:"local,omitempty" yamltags:"oneOf=build"` + + // GoogleCloudBuild *beta* describes how to do a remote build on + // [Google Cloud Build](https://cloud.google.com/cloud-build/). + GoogleCloudBuild *GoogleCloudBuild `yaml:"googleCloudBuild,omitempty" yamltags:"oneOf=build"` + + // Cluster *beta* describes how to do an on-cluster build. + Cluster *ClusterDetails `yaml:"cluster,omitempty" yamltags:"oneOf=build"` +} + +// LocalBuild *beta* describes how to do a build on the local docker daemon +// and optionally push to a repository. +type LocalBuild struct { + // Push should images be pushed to a registry. + // If not specified, images are pushed only if the current Kubernetes context + // connects to a remote cluster. + Push *bool `yaml:"push,omitempty"` + + // UseDockerCLI use `docker` command-line interface instead of Docker Engine APIs. + UseDockerCLI bool `yaml:"useDockerCLI,omitempty"` + + // UseBuildkit use BuildKit to build Docker images. + UseBuildkit bool `yaml:"useBuildkit,omitempty"` +} + +// GoogleCloudBuild *beta* describes how to do a remote build on +// [Google Cloud Build](https://cloud.google.com/cloud-build/docs/). +// Docker and Jib artifacts can be built on Cloud Build. The `projectId` needs +// to be provided and the currently logged in user should be given permissions to trigger +// new builds. +type GoogleCloudBuild struct { + // ProjectID is the ID of your Cloud Platform Project. + // If it is not provided, Skaffold will guess it from the image name. + // For example, given the artifact image name `gcr.io/myproject/image`, Skaffold + // will use the `myproject` GCP project. + ProjectID string `yaml:"projectId,omitempty"` + + // DiskSizeGb is the disk size of the VM that runs the build. + // See [Cloud Build Reference](https://cloud.google.com/cloud-build/docs/api/reference/rest/v1/projects.builds#buildoptions). + DiskSizeGb int64 `yaml:"diskSizeGb,omitempty"` + + // MachineType is the type of the VM that runs the build. + // See [Cloud Build Reference](https://cloud.google.com/cloud-build/docs/api/reference/rest/v1/projects.builds#buildoptions). + MachineType string `yaml:"machineType,omitempty"` + + // Timeout is the amount of time (in seconds) that this build should be allowed to run. + // See [Cloud Build Reference](https://cloud.google.com/cloud-build/docs/api/reference/rest/v1/projects.builds#resource-build). + Timeout string `yaml:"timeout,omitempty"` + + // DockerImage is the image that runs a Docker build. + // See [Cloud Builders](https://cloud.google.com/cloud-build/docs/cloud-builders). + // Defaults to `gcr.io/cloud-builders/docker`. + DockerImage string `yaml:"dockerImage,omitempty"` + + // MavenImage is the image that runs a Maven build. + // See [Cloud Builders](https://cloud.google.com/cloud-build/docs/cloud-builders). + // Defaults to `gcr.io/cloud-builders/mvn`. + MavenImage string `yaml:"mavenImage,omitempty"` + + // GradleImage is the image that runs a Gradle build. + // See [Cloud Builders](https://cloud.google.com/cloud-build/docs/cloud-builders). + // Defaults to `gcr.io/cloud-builders/gradle`. + GradleImage string `yaml:"gradleImage,omitempty"` +} + +// LocalDir configures how Kaniko mounts sources directly via an `emptyDir` volume. +type LocalDir struct { + // InitImage is the image used to run init container which mounts kaniko context. + InitImage string `yaml:"initImage,omitempty"` +} + +// KanikoBuildContext contains the different fields available to specify +// a Kaniko build context. +type KanikoBuildContext struct { + // GCSBucket is the GCS bucket to which sources are uploaded. + // Kaniko will need access to that bucket to download the sources. + GCSBucket string `yaml:"gcsBucket,omitempty" yamltags:"oneOf=buildContext"` + + // LocalDir configures how Kaniko mounts sources directly via an `emptyDir` volume. + LocalDir *LocalDir `yaml:"localDir,omitempty" yamltags:"oneOf=buildContext"` +} + +// KanikoCache configures Kaniko caching. If a cache is specified, Kaniko will +// use a remote cache which will speed up builds. +type KanikoCache struct { + // Repo is a remote repository to store cached layers. If none is specified, one will be + // inferred from the image name. See [Kaniko Caching](https://github.com/GoogleContainerTools/kaniko#caching). + Repo string `yaml:"repo,omitempty"` + // HostPath specifies a path on the host that is mounted to each pod as read only cache volume containing base images. + // If set, must exist on each node and prepopulated with kaniko-warmer. + HostPath string `yaml:"hostPath,omitempty"` +} + +// ClusterDetails *beta* describes how to do an on-cluster build. +type ClusterDetails struct { + // HTTPProxy for kaniko pod. + HTTPProxy string `yaml:"HTTP_PROXY,omitempty"` + + // HTTPSProxy for kaniko pod. + HTTPSProxy string `yaml:"HTTPS_PROXY,omitempty"` + + // PullSecret is the path to the Google Cloud service account secret key file. + PullSecret string `yaml:"pullSecret,omitempty"` + + // PullSecretName is the name of the Kubernetes secret for pulling the files + // from the build context and pushing the final image. If given, the secret needs to + // contain the Google Cloud service account secret key under the key `kaniko-secret`. + // Defaults to `kaniko-secret`. + PullSecretName string `yaml:"pullSecretName,omitempty"` + + // Namespace is the Kubernetes namespace. + // Defaults to current namespace in Kubernetes configuration. + Namespace string `yaml:"namespace,omitempty"` + + // Timeout is the amount of time (in seconds) that this build is allowed to run. + // Defaults to 20 minutes (`20m`). + Timeout string `yaml:"timeout,omitempty"` + + // DockerConfig describes how to mount the local Docker configuration into a pod. + DockerConfig *DockerConfig `yaml:"dockerConfig,omitempty"` + + // Resources define the resource requirements for the kaniko pod. + Resources *ResourceRequirements `yaml:"resources,omitempty"` +} + +// DockerConfig contains information about the docker `config.json` to mount. +type DockerConfig struct { + // Path is the path to the docker `config.json`. + Path string `yaml:"path,omitempty"` + + // SecretName is the Kubernetes secret that contains the `config.json` Docker configuration. + // Note that the expected secret type is not 'kubernetes.io/dockerconfigjson' but 'Opaque'. + SecretName string `yaml:"secretName,omitempty"` +} + +// ResourceRequirements describes the resource requirements for the kaniko pod. +type ResourceRequirements struct { + // Requests [resource requests](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#resource-requests-and-limits-of-pod-and-container) for the Kaniko pod. + Requests *ResourceRequirement `yaml:"requests,omitempty"` + + // Limits [resource limits](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#resource-requests-and-limits-of-pod-and-container) for the Kaniko pod. + Limits *ResourceRequirement `yaml:"limits,omitempty"` +} + +// ResourceRequirement stores the CPU/Memory requirements for the pod. +type ResourceRequirement struct { + // CPU the number cores to be used. + // For example: `2`, `2.0` or `200m`. + CPU string `yaml:"cpu,omitempty"` + + // Memory the amount of memory to allocate to the pod. + // For example: `1Gi` or `1000Mi`. + Memory string `yaml:"memory,omitempty"` +} + +// TestCase is a list of structure tests to run on images that Skaffold builds. +type TestCase struct { + // ImageName is the artifact on which to run those tests. + // For example: `gcr.io/k8s-skaffold/example`. + ImageName string `yaml:"image" yamltags:"required"` + + // StructureTests lists the [Container Structure Tests](https://github.com/GoogleContainerTools/container-structure-test) + // to run on that artifact. + // For example: `["./test/*"]`. + StructureTests []string `yaml:"structureTests,omitempty"` +} + +// DeployConfig contains all the configuration needed by the deploy steps. +type DeployConfig struct { + // StatusCheckDeadlineSeconds *beta* is the deadline for deployments to stabilize in seconds. + StatusCheckDeadlineSeconds int `yaml:"statusCheckDeadlineSeconds,omitempty"` + DeployType `yaml:",inline"` +} + +// DeployType contains the specific implementation and parameters needed +// for the deploy step. Only one field should be populated. +type DeployType struct { + // HelmDeploy *beta* uses the `helm` CLI to apply the charts to the cluster. + HelmDeploy *HelmDeploy `yaml:"helm,omitempty" yamltags:"oneOf=deploy"` + + // KubectlDeploy *beta* uses a client side `kubectl apply` to deploy manifests. + // You'll need a `kubectl` CLI version installed that's compatible with your cluster. + KubectlDeploy *KubectlDeploy `yaml:"kubectl,omitempty" yamltags:"oneOf=deploy"` + + // KustomizeDeploy *beta* uses the `kustomize` CLI to "patch" a deployment for a target environment. + KustomizeDeploy *KustomizeDeploy `yaml:"kustomize,omitempty" yamltags:"oneOf=deploy"` +} + +// KubectlDeploy *beta* uses a client side `kubectl apply` to deploy manifests. +// You'll need a `kubectl` CLI version installed that's compatible with your cluster. +type KubectlDeploy struct { + // Manifests lists the Kubernetes yaml or json manifests. + // Defaults to `["k8s/*.yaml"]`. + Manifests []string `yaml:"manifests,omitempty"` + + // RemoteManifests lists Kubernetes manifests in remote clusters. + RemoteManifests []string `yaml:"remoteManifests,omitempty"` + + // Flags are additional flags passed to `kubectl`. + Flags KubectlFlags `yaml:"flags,omitempty"` +} + +// KubectlFlags are additional flags passed on the command +// line to kubectl either on every command (Global), on creations (Apply) +// or deletions (Delete). +type KubectlFlags struct { + // Global are additional flags passed on every command. + Global []string `yaml:"global,omitempty"` + + // Apply are additional flags passed on creations (`kubectl apply`). + Apply []string `yaml:"apply,omitempty"` + + // Delete are additional flags passed on deletions (`kubectl delete`). + Delete []string `yaml:"delete,omitempty"` +} + +// HelmDeploy *beta* uses the `helm` CLI to apply the charts to the cluster. +type HelmDeploy struct { + // Releases is a list of Helm releases. + Releases []HelmRelease `yaml:"releases,omitempty" yamltags:"required"` + + // Flags are additional option flags that are passed on the command + // line to `helm`. + Flags HelmDeployFlags `yaml:"flags,omitempty"` +} + +// HelmDeployFlags are additional option flags that are passed on the command +// line to `helm`. +type HelmDeployFlags struct { + // Global are additional flags passed on every command. + Global []string `yaml:"global,omitempty"` + + // Install are additional flags passed to (`helm install`). + Install []string `yaml:"install,omitempty"` + + // Upgrade are additional flags passed to (`helm upgrade`). + Upgrade []string `yaml:"upgrade,omitempty"` +} + +// KustomizeDeploy *beta* uses the `kustomize` CLI to "patch" a deployment for a target environment. +type KustomizeDeploy struct { + // KustomizePath is the path to Kustomization files. + // Defaults to `.`. + KustomizePath string `yaml:"path,omitempty"` + + // Flags are additional flags passed to `kubectl`. + Flags KubectlFlags `yaml:"flags,omitempty"` +} + +// HelmRelease describes a helm release to be deployed. +type HelmRelease struct { + // Name is the name of the Helm release. + Name string `yaml:"name,omitempty" yamltags:"required"` + + // ChartPath is the path to the Helm chart. + ChartPath string `yaml:"chartPath,omitempty" yamltags:"required"` + + // ValuesFiles are the paths to the Helm `values` files. + ValuesFiles []string `yaml:"valuesFiles,omitempty"` + + // Values are key-value pairs supplementing the Helm `values` file. + Values map[string]string `yaml:"values,omitempty,omitempty"` + + // Namespace is the Kubernetes namespace. + Namespace string `yaml:"namespace,omitempty"` + + // Version is the version of the chart. + Version string `yaml:"version,omitempty"` + + // SetValues are key-value pairs. + // If present, Skaffold will send `--set` flag to Helm CLI and append all pairs after the flag. + SetValues map[string]string `yaml:"setValues,omitempty"` + + // SetValueTemplates are key-value pairs. + // If present, Skaffold will try to parse the value part of each key-value pair using + // environment variables in the system, then send `--set` flag to Helm CLI and append + // all parsed pairs after the flag. + SetValueTemplates map[string]string `yaml:"setValueTemplates,omitempty"` + + // Wait if `true`, Skaffold will send `--wait` flag to Helm CLI. + // Defaults to `false`. + Wait bool `yaml:"wait,omitempty"` + + // RecreatePods if `true`, Skaffold will send `--recreate-pods` flag to Helm CLI. + // Defaults to `false`. + RecreatePods bool `yaml:"recreatePods,omitempty"` + + // SkipBuildDependencies should build dependencies be skipped. + SkipBuildDependencies bool `yaml:"skipBuildDependencies,omitempty"` + + // UseHelmSecrets instructs skaffold to use secrets plugin on deployment. + UseHelmSecrets bool `yaml:"useHelmSecrets,omitempty"` + + // Remote specifies whether the chart path is remote, or exists on the host filesystem. + // `remote: true` implies `skipBuildDependencies: true`. + Remote bool `yaml:"remote,omitempty"` + + // Overrides are key-value pairs. + // If present, Skaffold will build a Helm `values` file that overrides + // the original and use it to call Helm CLI (`--f` flag). + Overrides util.HelmOverrides `yaml:"overrides,omitempty"` + + // Packaged parameters for packaging helm chart (`helm package`). + Packaged *HelmPackaged `yaml:"packaged,omitempty"` + + // ImageStrategy adds image configurations to the Helm `values` file. + ImageStrategy HelmImageStrategy `yaml:"imageStrategy,omitempty"` +} + +// HelmPackaged parameters for packaging helm chart (`helm package`). +type HelmPackaged struct { + // Version sets the `version` on the chart to this semver version. + Version string `yaml:"version,omitempty"` + + // AppVersion sets the `appVersion` on the chart to this version. + AppVersion string `yaml:"appVersion,omitempty"` +} + +// HelmImageStrategy adds image configurations to the Helm `values` file. +type HelmImageStrategy struct { + HelmImageConfig `yaml:",inline"` +} + +// HelmImageConfig describes an image configuration. +type HelmImageConfig struct { + // HelmFQNConfig is the image configuration uses the syntax `IMAGE-NAME=IMAGE-REPOSITORY:IMAGE-TAG`. + HelmFQNConfig *HelmFQNConfig `yaml:"fqn,omitempty" yamltags:"oneOf=helmImageStrategy"` + + // HelmConventionConfig is the image configuration uses the syntax `IMAGE-NAME.repository=IMAGE-REPOSITORY, IMAGE-NAME.tag=IMAGE-TAG`. + HelmConventionConfig *HelmConventionConfig `yaml:"helm,omitempty" yamltags:"oneOf=helmImageStrategy"` +} + +// HelmFQNConfig is the image config to use the FullyQualifiedImageName as param to set. +type HelmFQNConfig struct { + // Property defines the image config. + Property string `yaml:"property,omitempty"` +} + +// HelmConventionConfig is the image config in the syntax of image.repository and image.tag. +type HelmConventionConfig struct { + // ExplicitRegistry separates `image.registry` to the image config syntax. Useful for some charts e.g. `postgresql`. + ExplicitRegistry bool `yaml:"explicitRegistry,omitempty"` +} + +// Artifact are the items that need to be built, along with the context in which +// they should be built. +type Artifact struct { + // ImageName is the name of the image to be built. + // For example: `gcr.io/k8s-skaffold/example`. + ImageName string `yaml:"image,omitempty" yamltags:"required"` + + // Workspace is the directory containing the artifact's sources. + // Defaults to `.`. + Workspace string `yaml:"context,omitempty"` + + // Sync *alpha* lists local files synced to pods instead + // of triggering an image build when modified. + Sync *Sync `yaml:"sync,omitempty"` + + // ArtifactType describes how to build an artifact. + ArtifactType `yaml:",inline"` +} + +// Sync *alpha* specifies what files to sync into the container. +// This is a list of sync rules indicating the intent to sync for source files. +type Sync struct { + // Manual lists manual sync rules indicating the source and destination. + Manual []*SyncRule `yaml:"manual,omitempty" yamltags:"oneOf=sync"` + + // Infer lists file patterns which may be synced into the container. + // The container destination is inferred by the builder. + // Currently only available for docker artifacts. + Infer []string `yaml:"infer,omitempty" yamltags:"oneOf=sync"` +} + +// SyncRule specifies which local files to sync to remote folders. +type SyncRule struct { + // Src is a glob pattern to match local paths against. + // Directories should be delimited by `/` on all platforms. + // For example: `"css/**/*.css"`. + Src string `yaml:"src,omitempty" yamltags:"required"` + + // Dest is the destination path in the container where the files should be synced to. + // For example: `"app/"` + Dest string `yaml:"dest,omitempty" yamltags:"required"` + + // Strip specifies the path prefix to remove from the source path when + // transplanting the files into the destination folder. + // For example: `"css/"` + Strip string `yaml:"strip,omitempty"` +} + +// Profile *beta* profiles are used to override any `build`, `test` or `deploy` configuration. +type Profile struct { + // Name is a unique profile name. + // For example: `profile-prod`. + Name string `yaml:"name,omitempty" yamltags:"required"` + + // Pipeline contains the definitions to replace the default skaffold pipeline. + Pipeline `yaml:",inline"` + + // Patches lists patches applied to the configuration. + // Patches use the JSON patch notation. + Patches []JSONPatch `yaml:"patches,omitempty"` + + // Activation criteria by which a profile can be auto-activated. + // The profile is auto-activated if any one of the activations are triggered. + // An activation is triggered if all of the criteria (env, kubeContext, command) are triggered. + Activation []Activation `yaml:"activation,omitempty"` +} + +// JSONPatch patch to be applied by a profile. +type JSONPatch struct { + // Op is the operation carried by the patch: `add`, `remove`, `replace`, `move`, `copy` or `test`. + // Defaults to `replace`. + Op string `yaml:"op,omitempty"` + + // Path is the position in the yaml where the operation takes place. + // For example, this targets the `dockerfile` of the first artifact built. + // For example: `/build/artifacts/0/docker/dockerfile`. + Path string `yaml:"path,omitempty" yamltags:"required"` + + // From is the source position in the yaml, used for `copy` or `move` operations. + From string `yaml:"from,omitempty"` + + // Value is the value to apply. Can be any portion of yaml. + Value *util.YamlpatchNode `yaml:"value,omitempty"` +} + +// Activation criteria by which a profile is auto-activated. +type Activation struct { + // Env is a `key=value` pair. The profile is auto-activated if an Environment + // Variable `key` has value `value`. + // For example: `ENV=production`. + Env string `yaml:"env,omitempty"` + + // KubeContext is a Kubernetes context for which the profile is auto-activated. + // For example: `minikube`. + KubeContext string `yaml:"kubeContext,omitempty"` + + // Command is a Skaffold command for which the profile is auto-activated. + // For example: `dev`. + Command string `yaml:"command,omitempty"` +} + +// ArtifactType describes how to build an artifact. +type ArtifactType struct { + // DockerArtifact *beta* describes an artifact built from a Dockerfile. + DockerArtifact *DockerArtifact `yaml:"docker,omitempty" yamltags:"oneOf=artifact"` + + // BazelArtifact *beta* requires bazel CLI to be installed and the sources to + // contain [Bazel](https://bazel.build/) configuration files. + BazelArtifact *BazelArtifact `yaml:"bazel,omitempty" yamltags:"oneOf=artifact"` + + // JibMavenArtifact *alpha* builds images using the + // [Jib plugin for Maven](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin). + JibMavenArtifact *JibMavenArtifact `yaml:"jibMaven,omitempty" yamltags:"oneOf=artifact"` + + // JibGradleArtifact *alpha* builds images using the + // [Jib plugin for Gradle](https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin). + JibGradleArtifact *JibGradleArtifact `yaml:"jibGradle,omitempty" yamltags:"oneOf=artifact"` + + // KanikoArtifact *alpha* builds images using [kaniko](https://github.com/GoogleContainerTools/kaniko). + KanikoArtifact *KanikoArtifact `yaml:"kaniko,omitempty" yamltags:"oneOf=artifact"` + + // CustomArtifact *alpha* builds images using a custom build script written by the user. + CustomArtifact *CustomArtifact `yaml:"custom,omitempty" yamltags:"oneOf=artifact"` +} + +// CustomArtifact *alpha* describes an artifact built from a custom build script +// written by the user. It can be used to build images with builders that aren't directly integrated with skaffold. +type CustomArtifact struct { + // BuildCommand is the command executed to build the image. + BuildCommand string `yaml:"buildCommand,omitempty"` + // Dependencies are the file dependencies that skaffold should watch for both rebuilding and file syncing for this artifact. + Dependencies *CustomDependencies `yaml:"dependencies,omitempty"` +} + +// CustomDependencies *alpha* is used to specify dependencies for an artifact built by a custom build script. +// Either `dockerfile` or `paths` should be specified for file watching to work as expected. +type CustomDependencies struct { + // Dockerfile should be set if the artifact is built from a Dockerfile, from which skaffold can determine dependencies. + Dockerfile *DockerfileDependency `yaml:"dockerfile,omitempty" yamltags:"oneOf=dependency"` + // Command represents a custom command that skaffold executes to obtain dependencies. The output of this command *must* be a valid JSON array. + Command string `yaml:"command,omitempty" yamltags:"oneOf=dependency"` + // Paths should be set to the file dependencies for this artifact, so that the skaffold file watcher knows when to rebuild and perform file synchronization. + Paths []string `yaml:"paths,omitempty" yamltags:"oneOf=dependency"` + // Ignore specifies the paths that should be ignored by skaffold's file watcher. If a file exists in both `paths` and in `ignore`, it will be ignored, and will be excluded from both rebuilds and file synchronization. + // Will only work in conjunction with `paths`. + Ignore []string `yaml:"ignore,omitempty"` +} + +// DockerfileDependency *alpha* is used to specify a custom build artifact that is built from a Dockerfile. This allows skaffold to determine dependencies from the Dockerfile. +type DockerfileDependency struct { + // Path locates the Dockerfile relative to workspace. + Path string `yaml:"path,omitempty"` + + // BuildArgs are arguments passed to the docker build. + // It also accepts environment variables via the go template syntax. + // For example: `{"key1": "value1", "key2": "value2", "key3": "{{.ENV_VARIABLE}}"}`. + BuildArgs map[string]*string `yaml:"buildArgs,omitempty"` +} + +// KanikoArtifact *alpha* describes an artifact built from a Dockerfile, +// with kaniko. +type KanikoArtifact struct { + // AdditionalFlags are additional flags to be passed to Kaniko command line. + // See [Kaniko Additional Flags](https://github.com/GoogleContainerTools/kaniko#additional-flags). + // Deprecated - instead the named, unique fields should be used, e.g. `buildArgs`, `cache`, `target`. + AdditionalFlags []string `yaml:"flags,omitempty"` + + // DockerfilePath locates the Dockerfile relative to workspace. + // Defaults to `Dockerfile`. + DockerfilePath string `yaml:"dockerfile,omitempty"` + + // Target is the Dockerfile target name to build. + Target string `yaml:"target,omitempty"` + + // BuildArgs are arguments passed to the docker build. + // It also accepts environment variables via the go template syntax. + // For example: `{"key1": "value1", "key2": "value2", "key3": "{{.ENV_VARIABLE}}"}`. + BuildArgs map[string]*string `yaml:"buildArgs,omitempty"` + + // BuildContext is where the build context for this artifact resides. + BuildContext *KanikoBuildContext `yaml:"buildContext,omitempty"` + + // Image is the Docker image used by the Kaniko pod. + // Defaults to the latest released version of `gcr.io/kaniko-project/executor`. + Image string `yaml:"image,omitempty"` + + // Cache configures Kaniko caching. If a cache is specified, Kaniko will + // use a remote cache which will speed up builds. + Cache *KanikoCache `yaml:"cache,omitempty"` + + // Reproducible is used to strip timestamps out of the built image. + Reproducible bool `yaml:"reproducible,omitempty"` +} + +// DockerArtifact *beta* describes an artifact built from a Dockerfile, +// usually using `docker build`. +type DockerArtifact struct { + // DockerfilePath locates the Dockerfile relative to workspace. + // Defaults to `Dockerfile`. + DockerfilePath string `yaml:"dockerfile,omitempty"` + + // Target is the Dockerfile target name to build. + Target string `yaml:"target,omitempty"` + + // BuildArgs are arguments passed to the docker build. + // For example: `{"key1": "value1", "key2": "value2"}`. + BuildArgs map[string]*string `yaml:"buildArgs,omitempty"` + + // NetworkMode is passed through to docker and overrides the + // network configuration of docker builder. If unset, use whatever + // is configured in the underlying docker daemon. Valid modes are + // `host`: use the host's networking stack. + // `bridge`: use the bridged network configuration. + // `none`: no networking in the container. + NetworkMode string `yaml:"network,omitempty"` + + // CacheFrom lists the Docker images used as cache sources. + // For example: `["golang:1.10.1-alpine3.7", "alpine:3.7"]`. + CacheFrom []string `yaml:"cacheFrom,omitempty"` + + // NoCache used to pass in --no-cache to docker build to prevent caching. + NoCache bool `yaml:"noCache,omitempty"` +} + +// BazelArtifact *beta* describes an artifact built with [Bazel](https://bazel.build/). +type BazelArtifact struct { + // BuildTarget is the `bazel build` target to run. + // For example: `//:skaffold_example.tar`. + BuildTarget string `yaml:"target,omitempty" yamltags:"required"` + + // BuildArgs are additional args to pass to `bazel build`. + // For example: `["-flag", "--otherflag"]`. + BuildArgs []string `yaml:"args,omitempty"` +} + +// JibMavenArtifact *alpha* builds images using the +// [Jib plugin for Maven](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin). +type JibMavenArtifact struct { + // Module selects which Maven module to build, for a multi module project. + Module string `yaml:"module,omitempty"` + + // Profile selects which Maven profile to activate. + Profile string `yaml:"profile,omitempty"` + + // Flags are additional build flags passed to Maven. + // For example: `["-x", "-DskipTests"]`. + Flags []string `yaml:"args,omitempty"` +} + +// JibGradleArtifact *alpha* builds images using the +// [Jib plugin for Gradle](https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin). +type JibGradleArtifact struct { + // Project selects which Gradle project to build. + Project string `yaml:"project,omitempty"` + + // Flags are additional build flags passed to Gradle. + // For example: `["--no-build-cache"]`. + Flags []string `yaml:"args,omitempty"` +} diff --git a/pkg/skaffold/schema/v1beta13/upgrade.go b/pkg/skaffold/schema/v1beta13/upgrade.go new file mode 100755 index 00000000000..8af20dff5d6 --- /dev/null +++ b/pkg/skaffold/schema/v1beta13/upgrade.go @@ -0,0 +1,37 @@ +/* +Copyright 2019 The Skaffold 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 v1beta13 + +import ( + next "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/util" + pkgutil "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" +) + +// Upgrade upgrades a configuration to the next version. +// Config changes from v1beta13 to v1beta14 +// 1. No Additions +// 2. No removals +// 3. No Updates +func (config *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) { + var newConfig next.SkaffoldConfig + + pkgutil.CloneThroughJSON(config, &newConfig) + newConfig.APIVersion = next.Version + + return &newConfig, nil +} diff --git a/pkg/skaffold/schema/v1beta13/upgrade_test.go b/pkg/skaffold/schema/v1beta13/upgrade_test.go new file mode 100755 index 00000000000..390fc9b30cd --- /dev/null +++ b/pkg/skaffold/schema/v1beta13/upgrade_test.go @@ -0,0 +1,149 @@ +/* +Copyright 2019 The Skaffold 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 v1beta13 + +import ( + "testing" + + next "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" + "github.com/GoogleContainerTools/skaffold/testutil" + yaml "gopkg.in/yaml.v2" +) + +func TestUpgrade(t *testing.T) { + yaml := `apiVersion: skaffold/v1beta13 +kind: Config +build: + artifacts: + - image: gcr.io/k8s-skaffold/skaffold-example + docker: + dockerfile: path/to/Dockerfile + - image: gcr.io/k8s-skaffold/bazel + bazel: + target: //mytarget + googleCloudBuild: + projectId: test-project +test: + - image: gcr.io/k8s-skaffold/skaffold-example + structureTests: + - ./test/* +deploy: + kubectl: + manifests: + - k8s-* +profiles: + - name: test profile + build: + artifacts: + - image: gcr.io/k8s-skaffold/skaffold-example + kaniko: + buildContext: + gcsBucket: skaffold-kaniko + cache: {} + cluster: + pullSecretName: e2esecret + namespace: default + test: + - image: gcr.io/k8s-skaffold/skaffold-example + structureTests: + - ./test/* + deploy: + kubectl: + manifests: + - k8s-* + - name: test local + build: + artifacts: + - image: gcr.io/k8s-skaffold/skaffold-example + docker: + dockerfile: path/to/Dockerfile + local: + push: false + deploy: + kubectl: + manifests: + - k8s-* +` + expected := `apiVersion: skaffold/v1beta14 +kind: Config +build: + artifacts: + - image: gcr.io/k8s-skaffold/skaffold-example + docker: + dockerfile: path/to/Dockerfile + - image: gcr.io/k8s-skaffold/bazel + bazel: + target: //mytarget + googleCloudBuild: + projectId: test-project +test: + - image: gcr.io/k8s-skaffold/skaffold-example + structureTests: + - ./test/* +deploy: + kubectl: + manifests: + - k8s-* +profiles: + - name: test profile + build: + artifacts: + - image: gcr.io/k8s-skaffold/skaffold-example + kaniko: + buildContext: + gcsBucket: skaffold-kaniko + cache: {} + cluster: + pullSecretName: e2esecret + namespace: default + test: + - image: gcr.io/k8s-skaffold/skaffold-example + structureTests: + - ./test/* + deploy: + kubectl: + manifests: + - k8s-* + - name: test local + build: + artifacts: + - image: gcr.io/k8s-skaffold/skaffold-example + docker: + dockerfile: path/to/Dockerfile + local: + push: false + deploy: + kubectl: + manifests: + - k8s-* +` + verifyUpgrade(t, yaml, expected) +} + +func verifyUpgrade(t *testing.T, input, output string) { + config := NewSkaffoldConfig() + err := yaml.UnmarshalStrict([]byte(input), config) + testutil.CheckErrorAndDeepEqual(t, false, err, Version, config.GetVersion()) + + upgraded, err := config.Upgrade() + testutil.CheckError(t, false, err) + + expected := next.NewSkaffoldConfig() + err = yaml.UnmarshalStrict([]byte(output), expected) + + testutil.CheckErrorAndDeepEqual(t, false, err, expected, upgraded) +} diff --git a/pkg/skaffold/schema/versions.go b/pkg/skaffold/schema/versions.go index ab3f78810df..15031325c60 100644 --- a/pkg/skaffold/schema/versions.go +++ b/pkg/skaffold/schema/versions.go @@ -21,7 +21,7 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - "gopkg.in/yaml.v2" + yaml "gopkg.in/yaml.v2" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/apiversion" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" @@ -35,6 +35,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1beta10" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1beta11" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1beta12" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1beta13" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1beta2" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1beta3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1beta4" @@ -68,6 +69,7 @@ var SchemaVersions = Versions{ {v1beta10.Version, v1beta10.NewSkaffoldConfig}, {v1beta11.Version, v1beta11.NewSkaffoldConfig}, {v1beta12.Version, v1beta12.NewSkaffoldConfig}, + {v1beta13.Version, v1beta13.NewSkaffoldConfig}, {latest.Version, latest.NewSkaffoldConfig}, } From 22555461e9091bdaa89e6dcd85a0417f5cea74a6 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Thu, 29 Aug 2019 10:16:51 +0200 Subject: [PATCH 56/69] Allow users to override the run-id Fixes #2745 Signed-off-by: David Gageot --- integration/run_test.go | 32 ++++++++++++++++++++++++++++++++ pkg/skaffold/runner/new.go | 3 ++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/integration/run_test.go b/integration/run_test.go index d2abd641ed6..f669c4ac746 100644 --- a/integration/run_test.go +++ b/integration/run_test.go @@ -17,6 +17,7 @@ limitations under the License. package integration import ( + "strings" "testing" "github.com/GoogleContainerTools/skaffold/integration/skaffold" @@ -146,3 +147,34 @@ func TestRun(t *testing.T) { }) } } + +func TestRunIdempotent(t *testing.T) { + if testing.Short() { + t.Skip("skipping integration test") + } + if ShouldRunGCPOnlyTests() { + t.Skip("skipping test that is not gcp only") + } + + ns, _, deleteNs := SetupNamespace(t) + defer deleteNs() + + // The first `skaffold run` creates resources (deployment.apps/leeroy-web, service/leeroy-app, deployment.apps/leeroy-app) + out := skaffold.Run("-l", "skaffold.dev/run-id=notunique").InDir("examples/microservices").InNs(ns.Name).RunOrFailOutput(t) + firstOut := string(out) + if strings.Count(firstOut, "created") == 0 { + t.Errorf("resources should have been created: %s", firstOut) + } + + // Because we use the same custom `run-id`, the second `skaffold run` is idempotent: + // + It has nothing to rebuild + // + It leaves all resources unchanged + out = skaffold.Run("-l", "skaffold.dev/run-id=notunique").InDir("examples/microservices").InNs(ns.Name).RunOrFailOutput(t) + secondOut := string(out) + if strings.Count(secondOut, "created") != 0 { + t.Errorf("no resource should have been created: %s", secondOut) + } + if !strings.Contains(secondOut, "leeroy-web: Found") || !strings.Contains(secondOut, "leeroy-app: Found") { + t.Errorf("both artifacts should be in cache: %s", secondOut) + } +} diff --git a/pkg/skaffold/runner/new.go b/pkg/skaffold/runner/new.go index 5fa0aaa4cda..6bdc072eee7 100644 --- a/pkg/skaffold/runner/new.go +++ b/pkg/skaffold/runner/new.go @@ -71,7 +71,8 @@ func NewForConfig(runCtx *runcontext.RunContext) (*SkaffoldRunner, error) { } defaultLabeller := deploy.NewLabeller("") - labellers := []deploy.Labeller{&runCtx.Opts, builder, deployer, tagger, defaultLabeller} + // runCtx.Opts is last to let users override/remove any label + labellers := []deploy.Labeller{builder, deployer, tagger, defaultLabeller, &runCtx.Opts} builder, tester, deployer = WithTimings(builder, tester, deployer, runCtx.Opts.CacheArtifacts) if runCtx.Opts.Notification { From f7ee78a5ebef99b6c8bf82ade173ecef0321cae3 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Thu, 29 Aug 2019 16:54:04 +0200 Subject: [PATCH 57/69] =?UTF-8?q?Print=20the=20kubectl=20version=20only=20?= =?UTF-8?q?if=20there=E2=80=99s=20a=20warning?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See 2740 Signed-off-by: David Gageot --- pkg/skaffold/deploy/kubectl.go | 2 +- pkg/skaffold/deploy/kustomize.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/skaffold/deploy/kubectl.go b/pkg/skaffold/deploy/kubectl.go index 751456af49c..4665973da4b 100644 --- a/pkg/skaffold/deploy/kubectl.go +++ b/pkg/skaffold/deploy/kubectl.go @@ -72,8 +72,8 @@ func (k *KubectlDeployer) Labels() map[string]string { // Deploy templates the provided manifests with a simple `find and replace` and // runs `kubectl apply` on those manifests func (k *KubectlDeployer) Deploy(ctx context.Context, out io.Writer, builds []build.Artifact, labellers []Labeller) *Result { - color.Default.Fprintln(out, "kubectl client version:", k.kubectl.Version(ctx)) if err := k.kubectl.CheckVersion(ctx); err != nil { + color.Default.Fprintln(out, "kubectl client version:", k.kubectl.Version(ctx)) color.Default.Fprintln(out, err) } diff --git a/pkg/skaffold/deploy/kustomize.go b/pkg/skaffold/deploy/kustomize.go index 46c8a4bde98..d55e753b2f9 100644 --- a/pkg/skaffold/deploy/kustomize.go +++ b/pkg/skaffold/deploy/kustomize.go @@ -94,8 +94,8 @@ func (k *KustomizeDeployer) Labels() map[string]string { // Deploy runs `kubectl apply` on the manifest generated by kustomize. func (k *KustomizeDeployer) Deploy(ctx context.Context, out io.Writer, builds []build.Artifact, labellers []Labeller) *Result { - color.Default.Fprintln(out, "kubectl client version:", k.kubectl.Version(ctx)) if err := k.kubectl.CheckVersion(ctx); err != nil { + color.Default.Fprintln(out, "kubectl client version:", k.kubectl.Version(ctx)) color.Default.Fprintln(out, err) } From 70c26637fab9aa537cd1bab66e93ea33291b6f19 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Thu, 29 Aug 2019 16:10:57 +0200 Subject: [PATCH 58/69] On windows, set -rwxr-xr-x-- on files in build context Fix #1470 Signed-off-by: David Gageot --- pkg/skaffold/util/tar.go | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/pkg/skaffold/util/tar.go b/pkg/skaffold/util/tar.go index c3ad11ad2b5..266ae957129 100644 --- a/pkg/skaffold/util/tar.go +++ b/pkg/skaffold/util/tar.go @@ -22,6 +22,7 @@ import ( "io" "os" "path/filepath" + "runtime" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -102,7 +103,7 @@ func addFileToTar(root string, src string, dst string, tw *tar.Writer) error { } tarHeader.Name = tarPath - if err := tw.WriteHeader(tarHeader); err != nil { + if err := writeHeader(tw, tarHeader); err != nil { return err } case mode.IsRegular(): @@ -112,7 +113,7 @@ func addFileToTar(root string, src string, dst string, tw *tar.Writer) error { } tarHeader.Name = tarPath - if err := tw.WriteHeader(tarHeader); err != nil { + if err := writeHeader(tw, tarHeader); err != nil { return err } @@ -140,7 +141,7 @@ func addFileToTar(root string, src string, dst string, tw *tar.Writer) error { return err } tarHeader.Name = tarPath - if err := tw.WriteHeader(tarHeader); err != nil { + if err := writeHeader(tw, tarHeader); err != nil { return err } default: @@ -150,9 +151,30 @@ func addFileToTar(root string, src string, dst string, tw *tar.Writer) error { if err != nil { return err } - if err := tw.WriteHeader(tarHeader); err != nil { + if err := writeHeader(tw, tarHeader); err != nil { return err } } return nil } + +// Code copied from https://github.com/moby/moby/blob/master/pkg/archive/archive_windows.go +func writeHeader(tw *tar.Writer, tarHeader *tar.Header) error { + if runtime.GOOS == "windows" { + tarHeader.Mode = int64(chmodTarEntry(os.FileMode(tarHeader.Mode))) + } + + return tw.WriteHeader(tarHeader) +} + +// Code copied from https://github.com/moby/moby/blob/master/pkg/archive/archive_windows.go +func chmodTarEntry(perm os.FileMode) os.FileMode { + //perm &= 0755 // this 0-ed out tar flags (like link, regular file, directory marker etc.) + permPart := perm & os.ModePerm + noPermPart := perm &^ os.ModePerm + // Add the x bit: make everything +x from windows + permPart |= 0111 + permPart &= 0755 + + return noPermPart | permPart +} From d2d71f3879f9bb92e55577b14ad9e357ed0f259b Mon Sep 17 00:00:00 2001 From: Brian de Alwis Date: Thu, 29 Aug 2019 11:38:47 -0400 Subject: [PATCH 59/69] Turn Jib init plugin names into a proper enum type (#2748) --- pkg/skaffold/initializer/init.go | 3 ++- pkg/skaffold/initializer/init_test.go | 36 +++++++++++++-------------- pkg/skaffold/jib/jib.go | 31 +++++++++++++++++++++++ pkg/skaffold/jib/jib_init.go | 16 ++++-------- pkg/skaffold/jib/jib_init_test.go | 30 +++++++++++----------- pkg/skaffold/jib/jib_test.go | 7 ++++++ 6 files changed, 78 insertions(+), 45 deletions(-) diff --git a/pkg/skaffold/initializer/init.go b/pkg/skaffold/initializer/init.go index 443f3b664af..2517895d255 100644 --- a/pkg/skaffold/initializer/init.go +++ b/pkg/skaffold/initializer/init.go @@ -281,7 +281,8 @@ func processCliArtifacts(artifacts []string) ([]builderImagePair, error) { pair := builderImagePair{Builder: parsed.Payload, ImageName: a.Image} pairs = append(pairs, pair) - case jib.JibGradle, jib.JibMaven: + // FIXME: shouldn't use a human-readable name? + case jib.JibGradle.Name(), jib.JibMaven.Name(): parsed := struct { Payload jib.Jib `json:"payload"` }{} diff --git a/pkg/skaffold/initializer/init_test.go b/pkg/skaffold/initializer/init_test.go index 0fe5f5c5f95..5fe38213eff 100644 --- a/pkg/skaffold/initializer/init_test.go +++ b/pkg/skaffold/initializer/init_test.go @@ -38,14 +38,14 @@ func TestPrintAnalyzeJSON(t *testing.T) { }{ { description: "builders and images with pairs", - pairs: []builderImagePair{{jib.Jib{BuilderName: jib.JibGradle, Image: "image1", FilePath: "build.gradle", Project: "project"}, "image1"}}, + pairs: []builderImagePair{{jib.Jib{BuilderName: jib.JibGradle.Name(), Image: "image1", FilePath: "build.gradle", Project: "project"}, "image1"}}, builders: []InitBuilder{docker.Docker{File: "Dockerfile"}}, images: []string{"image2"}, expected: `{"builders":[{"name":"Jib Gradle Plugin","payload":{"image":"image1","path":"build.gradle","project":"project"}},{"name":"Docker","payload":{"path":"Dockerfile"}}],"images":[{"name":"image1","foundMatch":true},{"name":"image2","foundMatch":false}]}`, }, { description: "builders and images with no pairs", - builders: []InitBuilder{jib.Jib{BuilderName: jib.JibGradle, FilePath: "build.gradle", Project: "project"}, docker.Docker{File: "Dockerfile"}}, + builders: []InitBuilder{jib.Jib{BuilderName: jib.JibGradle.Name(), FilePath: "build.gradle", Project: "project"}, docker.Docker{File: "Dockerfile"}}, images: []string{"image1", "image2"}, expected: `{"builders":[{"name":"Jib Gradle Plugin","payload":{"path":"build.gradle","project":"project"}},{"name":"Docker","payload":{"path":"Dockerfile"}}],"images":[{"name":"image1","foundMatch":false},{"name":"image2","foundMatch":false}]}`, }, @@ -289,10 +289,10 @@ func fakeValidateDockerfile(path string) bool { func fakeValidateJibConfig(path string) []jib.Jib { if strings.HasSuffix(path, "build.gradle") { - return []jib.Jib{{BuilderName: jib.JibGradle, FilePath: path}} + return []jib.Jib{{BuilderName: jib.JibGradle.Name(), FilePath: path}} } if strings.HasSuffix(path, "pom.xml") { - return []jib.Jib{{BuilderName: jib.JibMaven, FilePath: path}} + return []jib.Jib{{BuilderName: jib.JibMaven.Name(), FilePath: path}} } return nil } @@ -326,7 +326,7 @@ func TestResolveBuilderImages(t *testing.T) { }, { description: "prompt for multiple builders and images", - buildConfigs: []InitBuilder{docker.Docker{File: "Dockerfile1"}, jib.Jib{BuilderName: jib.JibGradle, FilePath: "build.gradle"}, jib.Jib{BuilderName: jib.JibMaven, Project: "project", FilePath: "pom.xml"}}, + buildConfigs: []InitBuilder{docker.Docker{File: "Dockerfile1"}, jib.Jib{BuilderName: jib.JibGradle.Name(), FilePath: "build.gradle"}, jib.Jib{BuilderName: jib.JibMaven.Name(), Project: "project", FilePath: "pom.xml"}}, images: []string{"image1", "image2"}, shouldMakeChoice: true, expectedPairs: []builderImagePair{ @@ -335,7 +335,7 @@ func TestResolveBuilderImages(t *testing.T) { ImageName: "image1", }, { - Builder: jib.Jib{BuilderName: jib.JibGradle, FilePath: "build.gradle"}, + Builder: jib.Jib{BuilderName: jib.JibGradle.Name(), FilePath: "build.gradle"}, ImageName: "image2", }, }, @@ -371,15 +371,15 @@ func TestAutoSelectBuilders(t *testing.T) { description: "no automatic matches", builderConfigs: []InitBuilder{ docker.Docker{File: "Dockerfile"}, - jib.Jib{BuilderName: jib.JibGradle, FilePath: "build.gradle"}, - jib.Jib{BuilderName: jib.JibMaven, FilePath: "pom.xml", Image: "not a k8s image"}, + jib.Jib{BuilderName: jib.JibGradle.Name(), FilePath: "build.gradle"}, + jib.Jib{BuilderName: jib.JibMaven.Name(), FilePath: "pom.xml", Image: "not a k8s image"}, }, images: []string{"image1", "image2"}, expectedPairs: nil, expectedBuildersLeft: []InitBuilder{ docker.Docker{File: "Dockerfile"}, - jib.Jib{BuilderName: jib.JibGradle, FilePath: "build.gradle"}, - jib.Jib{BuilderName: jib.JibMaven, FilePath: "pom.xml", Image: "not a k8s image"}, + jib.Jib{BuilderName: jib.JibGradle.Name(), FilePath: "build.gradle"}, + jib.Jib{BuilderName: jib.JibMaven.Name(), FilePath: "pom.xml", Image: "not a k8s image"}, }, expectedFilteredImages: []string{"image1", "image2"}, }, @@ -387,17 +387,17 @@ func TestAutoSelectBuilders(t *testing.T) { description: "automatic jib matches", builderConfigs: []InitBuilder{ docker.Docker{File: "Dockerfile"}, - jib.Jib{BuilderName: jib.JibGradle, FilePath: "build.gradle", Image: "image1"}, - jib.Jib{BuilderName: jib.JibMaven, FilePath: "pom.xml", Image: "image2"}, + jib.Jib{BuilderName: jib.JibGradle.Name(), FilePath: "build.gradle", Image: "image1"}, + jib.Jib{BuilderName: jib.JibMaven.Name(), FilePath: "pom.xml", Image: "image2"}, }, images: []string{"image1", "image2", "image3"}, expectedPairs: []builderImagePair{ { - jib.Jib{BuilderName: jib.JibGradle, FilePath: "build.gradle", Image: "image1"}, + jib.Jib{BuilderName: jib.JibGradle.Name(), FilePath: "build.gradle", Image: "image1"}, "image1", }, { - jib.Jib{BuilderName: jib.JibMaven, FilePath: "pom.xml", Image: "image2"}, + jib.Jib{BuilderName: jib.JibMaven.Name(), FilePath: "pom.xml", Image: "image2"}, "image2", }, }, @@ -407,14 +407,14 @@ func TestAutoSelectBuilders(t *testing.T) { { description: "multiple matches for one image", builderConfigs: []InitBuilder{ - jib.Jib{BuilderName: jib.JibGradle, FilePath: "build.gradle", Image: "image1"}, - jib.Jib{BuilderName: jib.JibMaven, FilePath: "pom.xml", Image: "image1"}, + jib.Jib{BuilderName: jib.JibGradle.Name(), FilePath: "build.gradle", Image: "image1"}, + jib.Jib{BuilderName: jib.JibMaven.Name(), FilePath: "pom.xml", Image: "image1"}, }, images: []string{"image1", "image2"}, expectedPairs: nil, expectedBuildersLeft: []InitBuilder{ - jib.Jib{BuilderName: jib.JibGradle, FilePath: "build.gradle", Image: "image1"}, - jib.Jib{BuilderName: jib.JibMaven, FilePath: "pom.xml", Image: "image1"}, + jib.Jib{BuilderName: jib.JibGradle.Name(), FilePath: "build.gradle", Image: "image1"}, + jib.Jib{BuilderName: jib.JibMaven.Name(), FilePath: "pom.xml", Image: "image1"}, }, expectedFilteredImages: []string{"image1", "image2"}, }, diff --git a/pkg/skaffold/jib/jib.go b/pkg/skaffold/jib/jib.go index ac4137ede49..200a8c31743 100644 --- a/pkg/skaffold/jib/jib.go +++ b/pkg/skaffold/jib/jib.go @@ -39,6 +39,37 @@ const ( dotDotSlash = ".." + string(filepath.Separator) ) +// PluginType is an enum for the different supported Jib plugins. +type PluginType int + +// Define the different plugin types supported by Jib. +const ( + JibMaven PluginType = iota + JibGradle +) + +// ID returns the identifier for a Jib plugin type, suitable for external references (YAML, JSON, command-line, etc). +func (t PluginType) ID() string { + switch t { + case JibMaven: + return "maven" + case JibGradle: + return "gradle" + } + panic("Unknown Jib Plugin Type: " + string(t)) +} + +// Name provides a human-oriented label for a plugin type. +func (t PluginType) Name() string { + switch t { + case JibMaven: + return "Jib Maven Plugin" + case JibGradle: + return "Jib Gradle Plugin" + } + panic("Unknown Jib Plugin Type: " + string(t)) +} + // filesLists contains cached build/input dependencies type filesLists struct { // BuildDefinitions lists paths to build definitions that trigger a call out to Jib to refresh the pathMap, as well as a rebuild, upon changing diff --git a/pkg/skaffold/jib/jib_init.go b/pkg/skaffold/jib/jib_init.go index bab53f2f56e..a1485adece3 100644 --- a/pkg/skaffold/jib/jib_init.go +++ b/pkg/skaffold/jib/jib_init.go @@ -35,13 +35,6 @@ var ( ValidateJibConfigFunc = ValidateJibConfig ) -const ( - // JibGradle the name of the Jib Gradle Plugin - JibGradle = "Jib Gradle Plugin" - // JibMaven the name of the Jib Maven Plugin - JibMaven = "Jib Maven Plugin" -) - // Jib holds information about a Jib project type Jib struct { BuilderName string `json:"-"` @@ -76,7 +69,7 @@ func (j Jib) CreateArtifact(manifestImage string) *latest.Artifact { a.Workspace = workspace } - if j.BuilderName == JibMaven { + if j.BuilderName == JibMaven.Name() { jibMaven := &latest.JibMavenArtifact{} if j.Project != "" { jibMaven.Module = j.Project @@ -86,7 +79,7 @@ func (j Jib) CreateArtifact(manifestImage string) *latest.Artifact { } a.ArtifactType = latest.ArtifactType{JibMavenArtifact: jibMaven} - } else if j.BuilderName == JibGradle { + } else if j.BuilderName == JibGradle.Name() { jibGradle := &latest.JibGradleArtifact{} if j.Project != "" { jibGradle.Project = j.Project @@ -119,7 +112,8 @@ type jibJSON struct { // ValidateJibConfig checks if a file is a valid Jib configuration. Returns the list of Config objects corresponding to each Jib project built by the file, or nil if Jib is not configured. func ValidateJibConfig(path string) []Jib { // Determine whether maven or gradle - var builderType, executable, wrapper, taskName string + var builderType PluginType + var executable, wrapper, taskName string switch { case strings.HasSuffix(path, "pom.xml"): builderType = JibMaven @@ -162,7 +156,7 @@ func ValidateJibConfig(path string) []Jib { return nil } - results[i] = Jib{BuilderName: builderType, Image: parsedJSON.Image, FilePath: path, Project: parsedJSON.Project} + results[i] = Jib{BuilderName: builderType.Name(), Image: parsedJSON.Image, FilePath: path, Project: parsedJSON.Project} } return results } diff --git a/pkg/skaffold/jib/jib_init_test.go b/pkg/skaffold/jib/jib_init_test.go index ac643d06cc8..12fae3a5302 100644 --- a/pkg/skaffold/jib/jib_init_test.go +++ b/pkg/skaffold/jib/jib_init_test.go @@ -53,7 +53,7 @@ func TestValidateJibConfig(t *testing.T) { {"image":"image","project":"project"} `, expectedConfig: []Jib{ - {BuilderName: JibGradle, FilePath: "path/to/build.gradle", Image: "image", Project: "project"}, + {BuilderName: JibGradle.Name(), FilePath: "path/to/build.gradle", Image: "image", Project: "project"}, }, }, { @@ -67,8 +67,8 @@ BEGIN JIB JSON {"project":"project2"} `, expectedConfig: []Jib{ - {BuilderName: JibGradle, FilePath: "path/to/build.gradle", Image: "image", Project: "project1"}, - {BuilderName: JibGradle, FilePath: "path/to/build.gradle", Project: "project2"}, + {BuilderName: JibGradle.Name(), FilePath: "path/to/build.gradle", Image: "image", Project: "project1"}, + {BuilderName: JibGradle.Name(), FilePath: "path/to/build.gradle", Project: "project2"}, }, }, { @@ -78,7 +78,7 @@ BEGIN JIB JSON stdout: `BEGIN JIB JSON {"image":"image","project":"project"}`, expectedConfig: []Jib{ - {BuilderName: JibMaven, FilePath: "path/to/pom.xml", Image: "image", Project: "project"}, + {BuilderName: JibMaven.Name(), FilePath: "path/to/pom.xml", Image: "image", Project: "project"}, }, }, { @@ -92,8 +92,8 @@ BEGIN JIB JSON {"project":"project2"} `, expectedConfig: []Jib{ - {BuilderName: JibMaven, FilePath: "path/to/pom.xml", Image: "image", Project: "project1"}, - {BuilderName: JibMaven, FilePath: "path/to/pom.xml", Project: "project2"}, + {BuilderName: JibMaven.Name(), FilePath: "path/to/pom.xml", Image: "image", Project: "project1"}, + {BuilderName: JibMaven.Name(), FilePath: "path/to/pom.xml", Project: "project2"}, }, }, } @@ -113,22 +113,22 @@ func TestDescribe(t *testing.T) { }{ { description: "gradle without project", - config: Jib{BuilderName: JibGradle, FilePath: "path/to/build.gradle"}, + config: Jib{BuilderName: JibGradle.Name(), FilePath: "path/to/build.gradle"}, expectedPrompt: "Jib Gradle Plugin (path/to/build.gradle)", }, { description: "gradle with project", - config: Jib{BuilderName: JibGradle, Project: "project", FilePath: "path/to/build.gradle"}, + config: Jib{BuilderName: JibGradle.Name(), Project: "project", FilePath: "path/to/build.gradle"}, expectedPrompt: "Jib Gradle Plugin (project, path/to/build.gradle)", }, { description: "maven without project", - config: Jib{BuilderName: JibMaven, FilePath: "path/to/pom.xml"}, + config: Jib{BuilderName: JibMaven.Name(), FilePath: "path/to/pom.xml"}, expectedPrompt: "Jib Maven Plugin (path/to/pom.xml)", }, { description: "maven with project", - config: Jib{BuilderName: JibMaven, Project: "project", FilePath: "path/to/pom.xml"}, + config: Jib{BuilderName: JibMaven.Name(), Project: "project", FilePath: "path/to/pom.xml"}, expectedPrompt: "Jib Maven Plugin (project, path/to/pom.xml)", }, } @@ -149,7 +149,7 @@ func TestCreateArtifact(t *testing.T) { }{ { description: "jib gradle with image and project", - config: Jib{BuilderName: JibGradle, FilePath: filepath.Join("path", "to", "build.gradle"), Image: "image", Project: "project"}, + config: Jib{BuilderName: JibGradle.Name(), FilePath: filepath.Join("path", "to", "build.gradle"), Image: "image", Project: "project"}, manifestImage: "different-image", expectedArtifact: latest.Artifact{ ImageName: "image", @@ -161,7 +161,7 @@ func TestCreateArtifact(t *testing.T) { }, { description: "jib gradle without image and project", - config: Jib{BuilderName: JibGradle, FilePath: filepath.Join("path", "to", "build.gradle")}, + config: Jib{BuilderName: JibGradle.Name(), FilePath: filepath.Join("path", "to", "build.gradle")}, manifestImage: "different-image", expectedArtifact: latest.Artifact{ ImageName: "different-image", @@ -175,7 +175,7 @@ func TestCreateArtifact(t *testing.T) { }, { description: "jib maven with image and project", - config: Jib{BuilderName: JibMaven, FilePath: filepath.Join("path", "to", "pom.xml"), Image: "image", Project: "project"}, + config: Jib{BuilderName: JibMaven.Name(), FilePath: filepath.Join("path", "to", "pom.xml"), Image: "image", Project: "project"}, manifestImage: "different-image", expectedArtifact: latest.Artifact{ ImageName: "image", @@ -187,7 +187,7 @@ func TestCreateArtifact(t *testing.T) { }, { description: "jib maven without image and project", - config: Jib{BuilderName: JibMaven, FilePath: filepath.Join("path", "to", "pom.xml")}, + config: Jib{BuilderName: JibMaven.Name(), FilePath: filepath.Join("path", "to", "pom.xml")}, manifestImage: "different-image", expectedArtifact: latest.Artifact{ ImageName: "different-image", @@ -201,7 +201,7 @@ func TestCreateArtifact(t *testing.T) { }, { description: "ignore workspace", - config: Jib{BuilderName: JibGradle, FilePath: "build.gradle", Image: "image"}, + config: Jib{BuilderName: JibGradle.Name(), FilePath: "build.gradle", Image: "image"}, manifestImage: "different-image", expectedArtifact: latest.Artifact{ ImageName: "image", diff --git a/pkg/skaffold/jib/jib_test.go b/pkg/skaffold/jib/jib_test.go index f2ee3a26842..ae80e13ed80 100644 --- a/pkg/skaffold/jib/jib_test.go +++ b/pkg/skaffold/jib/jib_test.go @@ -26,6 +26,13 @@ import ( "github.com/GoogleContainerTools/skaffold/testutil" ) +func TestPluginType(t *testing.T) { + testutil.CheckDeepEqual(t, "maven", JibMaven.ID()) + testutil.CheckDeepEqual(t, "Jib Maven Plugin", JibMaven.Name()) + testutil.CheckDeepEqual(t, "gradle", JibGradle.ID()) + testutil.CheckDeepEqual(t, "Jib Gradle Plugin", JibGradle.Name()) +} + func TestGetDependencies(t *testing.T) { tmpDir, cleanup := testutil.NewTempDir(t) defer cleanup() From 254e929ca2af5ad122f73650852505a25e9ff432 Mon Sep 17 00:00:00 2001 From: Nick Kubala Date: Thu, 29 Aug 2019 11:09:16 -0700 Subject: [PATCH 60/69] Release v0.37.0 --- CHANGELOG.md | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27067b563d0..93284350bbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,87 @@ +# v0.37.0 Release - 08/29/2019 + +No new features in this release! + +Bug Fixes: + +* Use active gcloud credentials for executing cloudbuild when available [#2731](https://github.com/GoogleContainerTools/skaffold/pull/2731) +* Restore original images only if there are no remote manifests [#2746](https://github.com/GoogleContainerTools/skaffold/pull/2746) +* List manifests in the order given by the user [#2729](https://github.com/GoogleContainerTools/skaffold/pull/2729) +* Fix 'skaffold diagnose' for custom builder without dependencies [#2724](https://github.com/GoogleContainerTools/skaffold/pull/2724) +* Don't panic when dockerConfig isn't provided [#2735](https://github.com/GoogleContainerTools/skaffold/pull/2735) +* Don't set KanikoArtifact if CustomArtifact is set [#2716](https://github.com/GoogleContainerTools/skaffold/pull/2716) +* [Caching] Artifact’s config is an input to digest calculation [#2728](https://github.com/GoogleContainerTools/skaffold/pull/2728) +* Don’t fetch images that are aliases for scratch [#2720](https://github.com/GoogleContainerTools/skaffold/pull/2720) +* Implement exponential backoff for retrieving cloud build status [#2667](https://github.com/GoogleContainerTools/skaffold/pull/2667) +* Fix call to newPortForwardEntry constructor in kubectl_forwarder_test [#2703](https://github.com/GoogleContainerTools/skaffold/pull/2703) +* Add information about top level owner to port forward key [#2675](https://github.com/GoogleContainerTools/skaffold/pull/2675) +* Turn RPC State forwardedPorts into map keyed by the local port [#2659](https://github.com/GoogleContainerTools/skaffold/pull/2659) +* Show the duration of the deploy phase [#2739](https://github.com/GoogleContainerTools/skaffold/pull/2739) +* Configure jib.allowInsecureRegistries as required [#2674](https://github.com/GoogleContainerTools/skaffold/pull/2674) + +Updates & Refactors: + +* Pass extra env to the Docker CLI [#2737](https://github.com/GoogleContainerTools/skaffold/pull/2737) +* Improve manifest splitting. [#2727](https://github.com/GoogleContainerTools/skaffold/pull/2727) +* Bazel query should specify --output [#2712](https://github.com/GoogleContainerTools/skaffold/pull/2712) +* Print the output of failed integration tests [#2725](https://github.com/GoogleContainerTools/skaffold/pull/2725) +* We must handle every profile field type [#2726](https://github.com/GoogleContainerTools/skaffold/pull/2726) +* Fix CI scripts [#2736](https://github.com/GoogleContainerTools/skaffold/pull/2736) +* Directs "Download" button to Quickstart [#2695](https://github.com/GoogleContainerTools/skaffold/pull/2695) +* Small improvements to code coverage [#2719](https://github.com/GoogleContainerTools/skaffold/pull/2719) +* Don’t store log lines as mutable slices of bytes [#2721](https://github.com/GoogleContainerTools/skaffold/pull/2721) +* more debugging for kubectl portforward [#2707](https://github.com/GoogleContainerTools/skaffold/pull/2707) +* Remove time sensitive tests [#2655](https://github.com/GoogleContainerTools/skaffold/pull/2655) +* Log a warning and rebuild if needed when caching fails [#2685](https://github.com/GoogleContainerTools/skaffold/pull/2685) +* Improve logging warning when enountering profile field of unhandled type [#2691](https://github.com/GoogleContainerTools/skaffold/pull/2691) +* refactor: Add upgrade utility to handle all pipelines in a SkaffoldConfig [#2582](https://github.com/GoogleContainerTools/skaffold/pull/2582) +* Add struct for generate_pipeline to keep track of related data [#2686](https://github.com/GoogleContainerTools/skaffold/pull/2686) +* Add unit tests to kubectl forwarder [#2661](https://github.com/GoogleContainerTools/skaffold/pull/2661) +* separate checks + unit tests [#2676](https://github.com/GoogleContainerTools/skaffold/pull/2676) +* Add UPSTREAM_CLIENT_TYPE user agent environment variable to kaniko pod [#2723](https://github.com/GoogleContainerTools/skaffold/pull/2723) + +Docs: + +* Document Docker buildArgs as templated field [#2696](https://github.com/GoogleContainerTools/skaffold/pull/2696) +* Update cache-artifacts option usage language to reflect new default [#2711](https://github.com/GoogleContainerTools/skaffold/pull/2711) +* docs: clarify that tagged images in manifests are not replaced [#2598](https://github.com/GoogleContainerTools/skaffold/pull/2598) +* fix development guide link [#2710](https://github.com/GoogleContainerTools/skaffold/pull/2710) +* Update community section of README [#2682](https://github.com/GoogleContainerTools/skaffold/pull/2682) + +Huge thanks goes out to all of our contributors for this release: + +- Aaron Paz +- Andreas Sommer +- Appu +- Balint Pato +- bpopovschi +- Brian de Alwis +- Cedric Kring +- Chanseok Oh +- Charles-Henri GUERIN +- Cornelius Weig +- David Gageot +- Dmitri Moore +- Filip Krakowski +- Jason McClellan +- JieJhih Jhang +- Marlon Gamez +- Matt Brown +- Medya Ghazizadeh +- Michael Beaumont +- Nick Kubala +- Prashant Arya +- Priya Wadhwa +- Russell Wolf +- Sébastien Le Gall +- Sergei Morozov +- Tad Cordle +- Tanner Bruce +- Taylor Barrella +- Tejal Desai +- Tom Dickman + + # v0.36.0 Release - 08/15/2019 New Features: From ba58a46a1fe2442f22a0ada5ae9d5f9dad1ad21e Mon Sep 17 00:00:00 2001 From: David Gageot Date: Thu, 29 Aug 2019 21:46:26 +0200 Subject: [PATCH 61/69] Keep built artifacts always in their original order. (#2761) We should use the order used in the skaffold.yaml Fix #2680 Signed-off-by: David Gageot --- pkg/skaffold/build/cache/retrieve_test.go | 12 +++++ pkg/skaffold/build/util.go | 23 ++++++--- pkg/skaffold/build/util_test.go | 59 +++++++++++++++++++++++ pkg/skaffold/runner/dev_test.go | 2 +- 4 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 pkg/skaffold/build/util_test.go diff --git a/pkg/skaffold/build/cache/retrieve_test.go b/pkg/skaffold/build/cache/retrieve_test.go index beb7e17668a..1d5920fafb0 100644 --- a/pkg/skaffold/build/cache/retrieve_test.go +++ b/pkg/skaffold/build/cache/retrieve_test.go @@ -146,6 +146,9 @@ func TestCacheBuildLocal(t *testing.T) { t.CheckNoError(err) t.CheckDeepEqual(0, len(builder.built)) t.CheckDeepEqual(2, len(bRes)) + // Artifacts should always be returned in their original order + t.CheckDeepEqual("artifact1", bRes[0].ImageName) + t.CheckDeepEqual("artifact2", bRes[1].ImageName) // Third build: change one artifact's dependencies tmpDir.Write("dep1", "new content") @@ -155,6 +158,8 @@ func TestCacheBuildLocal(t *testing.T) { t.CheckNoError(err) t.CheckDeepEqual(1, len(builder.built)) t.CheckDeepEqual(2, len(bRes)) + t.CheckDeepEqual("artifact1", bRes[0].ImageName) + t.CheckDeepEqual("artifact2", bRes[1].ImageName) }) } @@ -218,6 +223,9 @@ func TestCacheBuildRemote(t *testing.T) { t.CheckNoError(err) t.CheckDeepEqual(2, len(builder.built)) t.CheckDeepEqual(2, len(bRes)) + // Artifacts should always be returned in their original order + t.CheckDeepEqual("artifact1", bRes[0].ImageName) + t.CheckDeepEqual("artifact2", bRes[1].ImageName) // Second build: both artifacts are read from cache builder = &mockBuilder{dockerDaemon: dockerDaemon, push: true} @@ -226,6 +234,8 @@ func TestCacheBuildRemote(t *testing.T) { t.CheckNoError(err) t.CheckDeepEqual(0, len(builder.built)) t.CheckDeepEqual(2, len(bRes)) + t.CheckDeepEqual("artifact1", bRes[0].ImageName) + t.CheckDeepEqual("artifact2", bRes[1].ImageName) // Third build: change one artifact's dependencies tmpDir.Write("dep1", "new content") @@ -235,5 +245,7 @@ func TestCacheBuildRemote(t *testing.T) { t.CheckNoError(err) t.CheckDeepEqual(1, len(builder.built)) t.CheckDeepEqual(2, len(bRes)) + t.CheckDeepEqual("artifact1", bRes[0].ImageName) + t.CheckDeepEqual("artifact2", bRes[1].ImageName) }) } diff --git a/pkg/skaffold/build/util.go b/pkg/skaffold/build/util.go index 9c6442622b6..f9301f4a837 100644 --- a/pkg/skaffold/build/util.go +++ b/pkg/skaffold/build/util.go @@ -18,19 +18,28 @@ package build // MergeWithPreviousBuilds merges previous or prebuilt build artifacts with // builds. If an artifact is already present in builds, the same artifact from -// previous will be ignored. +// previous will be replaced at the same position. func MergeWithPreviousBuilds(builds, previous []Artifact) []Artifact { - updatedBuilds := map[string]bool{} + updatedBuilds := map[string]Artifact{} for _, build := range builds { - updatedBuilds[build.ImageName] = true + updatedBuilds[build.ImageName] = build } + added := map[string]bool{} var merged []Artifact - merged = append(merged, builds...) - for _, b := range previous { - if !updatedBuilds[b.ImageName] { - merged = append(merged, b) + for _, artifact := range previous { + if updated, found := updatedBuilds[artifact.ImageName]; found { + merged = append(merged, updated) + } else { + merged = append(merged, artifact) + } + added[artifact.ImageName] = true + } + + for _, artifact := range builds { + if !added[artifact.ImageName] { + merged = append(merged, artifact) } } diff --git a/pkg/skaffold/build/util_test.go b/pkg/skaffold/build/util_test.go new file mode 100644 index 00000000000..0d95b7f17ee --- /dev/null +++ b/pkg/skaffold/build/util_test.go @@ -0,0 +1,59 @@ +/* +Copyright 2019 The Skaffold 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 build + +import ( + "fmt" + "testing" + + "github.com/GoogleContainerTools/skaffold/testutil" +) + +// TestMergeWithPreviousBuilds tests that artifacts are always kept in the same order +func TestMergeWithPreviousBuilds(t *testing.T) { + builds := MergeWithPreviousBuilds([]Artifact{artifact("img1", "tag1_1"), artifact("img2", "tag2_1")}, nil) + testutil.CheckDeepEqual(t, "img1:tag1_1,img2:tag2_1", tags(builds)) + + builds = MergeWithPreviousBuilds([]Artifact{artifact("img1", "tag1_2")}, builds) + testutil.CheckDeepEqual(t, "img1:tag1_2,img2:tag2_1", tags(builds)) + + builds = MergeWithPreviousBuilds([]Artifact{artifact("img2", "tag2_2")}, builds) + testutil.CheckDeepEqual(t, "img1:tag1_2,img2:tag2_2", tags(builds)) + + builds = MergeWithPreviousBuilds([]Artifact{artifact("img1", "tag1_3"), artifact("img2", "tag2_3")}, builds) + testutil.CheckDeepEqual(t, "img1:tag1_3,img2:tag2_3", tags(builds)) +} + +func artifact(image, tag string) Artifact { + return Artifact{ + ImageName: image, + Tag: tag, + } +} + +func tags(artifacts []Artifact) string { + var tags string + + for i, a := range artifacts { + if i > 0 { + tags += "," + } + tags += fmt.Sprintf("%s:%s", a.ImageName, a.Tag) + } + + return tags +} diff --git a/pkg/skaffold/runner/dev_test.go b/pkg/skaffold/runner/dev_test.go index 6f0ec7fc4a3..b93d97187cb 100644 --- a/pkg/skaffold/runner/dev_test.go +++ b/pkg/skaffold/runner/dev_test.go @@ -232,7 +232,7 @@ func TestDev(t *testing.T) { { Built: []string{"img2:2"}, Tested: []string{"img2:2"}, - Deployed: []string{"img2:2", "img1:1"}, + Deployed: []string{"img1:1", "img2:2"}, }, }, }, From 250bc8aa6798cc2fb104e4d4c945a041c267ed0f Mon Sep 17 00:00:00 2001 From: David Gageot Date: Thu, 29 Aug 2019 21:46:42 +0200 Subject: [PATCH 62/69] Indent deploy phase output (#2759) Signed-off-by: David Gageot --- go.mod | 1 + go.sum | 2 + pkg/skaffold/deploy/kubectl.go | 3 +- pkg/skaffold/deploy/kustomize.go | 3 +- vendor/github.com/segmentio/textio/.gitignore | 15 + vendor/github.com/segmentio/textio/LICENSE | 21 ++ vendor/github.com/segmentio/textio/README.md | 80 ++++++ vendor/github.com/segmentio/textio/go.mod | 3 + vendor/github.com/segmentio/textio/io.go | 63 ++++ vendor/github.com/segmentio/textio/prefix.go | 162 +++++++++++ vendor/github.com/segmentio/textio/tree.go | 271 ++++++++++++++++++ vendor/modules.txt | 14 +- 12 files changed, 630 insertions(+), 8 deletions(-) create mode 100644 vendor/github.com/segmentio/textio/.gitignore create mode 100644 vendor/github.com/segmentio/textio/LICENSE create mode 100644 vendor/github.com/segmentio/textio/README.md create mode 100644 vendor/github.com/segmentio/textio/go.mod create mode 100644 vendor/github.com/segmentio/textio/io.go create mode 100644 vendor/github.com/segmentio/textio/prefix.go create mode 100644 vendor/github.com/segmentio/textio/tree.go diff --git a/go.mod b/go.mod index 67d329eb50c..1efb5e766a2 100644 --- a/go.mod +++ b/go.mod @@ -58,6 +58,7 @@ require ( github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 // indirect github.com/prometheus/procfs v0.0.0-20181126161756-619930b0b471 // indirect github.com/rjeczalik/notify v0.9.2 + github.com/segmentio/textio v1.2.0 github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/sirupsen/logrus v1.4.1 github.com/spf13/cobra v0.0.4 diff --git a/go.sum b/go.sum index 27b6379b328..3742a7e7e90 100644 --- a/go.sum +++ b/go.sum @@ -227,6 +227,8 @@ github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNue github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/segmentio/textio v1.2.0 h1:Ug4IkV3kh72juJbG8azoSBlgebIbUUxVNrfFcKHfTSQ= +github.com/segmentio/textio v1.2.0/go.mod h1:+Rb7v0YVODP+tK5F7FD9TCkV7gOYx9IgLHWiqtvY8ag= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= diff --git a/pkg/skaffold/deploy/kubectl.go b/pkg/skaffold/deploy/kubectl.go index 4665973da4b..46458c818aa 100644 --- a/pkg/skaffold/deploy/kubectl.go +++ b/pkg/skaffold/deploy/kubectl.go @@ -23,6 +23,7 @@ import ( "strings" "github.com/pkg/errors" + "github.com/segmentio/textio" "github.com/sirupsen/logrus" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build" @@ -133,7 +134,7 @@ func (k *KubectlDeployer) Deploy(ctx context.Context, out io.Writer, builds []bu } } - if err := k.kubectl.Apply(ctx, out, manifests); err != nil { + if err := k.kubectl.Apply(ctx, textio.NewPrefixWriter(out, " - "), manifests); err != nil { event.DeployFailed(err) return NewDeployErrorResult(errors.Wrap(err, "kubectl error")) } diff --git a/pkg/skaffold/deploy/kustomize.go b/pkg/skaffold/deploy/kustomize.go index d55e753b2f9..7303e428515 100644 --- a/pkg/skaffold/deploy/kustomize.go +++ b/pkg/skaffold/deploy/kustomize.go @@ -37,6 +37,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner/runcontext" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" + "github.com/segmentio/textio" ) // kustomization is the content of a kustomization.yaml file. @@ -136,7 +137,7 @@ func (k *KustomizeDeployer) Deploy(ctx context.Context, out io.Writer, builds [] } } - if err := k.kubectl.Apply(ctx, out, manifests); err != nil { + if err := k.kubectl.Apply(ctx, textio.NewPrefixWriter(out, " - "), manifests); err != nil { event.DeployFailed(err) return NewDeployErrorResult(errors.Wrap(err, "kubectl error")) } diff --git a/vendor/github.com/segmentio/textio/.gitignore b/vendor/github.com/segmentio/textio/.gitignore new file mode 100644 index 00000000000..89b6c8158c5 --- /dev/null +++ b/vendor/github.com/segmentio/textio/.gitignore @@ -0,0 +1,15 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Emacs +*~ diff --git a/vendor/github.com/segmentio/textio/LICENSE b/vendor/github.com/segmentio/textio/LICENSE new file mode 100644 index 00000000000..06d4dea88ae --- /dev/null +++ b/vendor/github.com/segmentio/textio/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Segment + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/segmentio/textio/README.md b/vendor/github.com/segmentio/textio/README.md new file mode 100644 index 00000000000..5bbb588ef18 --- /dev/null +++ b/vendor/github.com/segmentio/textio/README.md @@ -0,0 +1,80 @@ +# textio [![CircleCI](https://circleci.com/gh/segmentio/textio.svg?style=shield)](https://circleci.com/gh/segmentio/textio) [![Go Report Card](https://goreportcard.com/badge/github.com/segmentio/textio)](https://goreportcard.com/report/github.com/segmentio/textio) [![GoDoc](https://godoc.org/github.com/segmentio/textio?status.svg)](https://godoc.org/github.com/segmentio/textio) +Go package providing tools for advanced text manipulations + +## Motivation + +This package aims to provide a sutie of tools to deal with text parsing and +formatting. It is intended to extend what the standard library already offers, +and make it easy to integrate with it. + +## Examples + +This sections presents a couple of examples about how to use this package. + +### Indenting + +Indentation is often a complex problem to solve when dealing with stream of text +that may be composed of multiple lines. To address this problem, this package +provides the `textio.PrefixWriter` type, which implements the `io.Writer` +interface and automatically prepends every line of output with a predefined +prefix. + +Here is an example: +```go +func copyIndent(w io.Writer, r io.Reader) error { + p := textio.NewPrefixWriter(w, "\t") + + // Copy data from an input stream into the PrefixWriter, all lines will + // be prefixed with a '\t' character. + if _, err := io.Copy(p, r); err != nil { + return err + } + + // Flushes any data buffered in the PrefixWriter, this is important in + // case the last line was not terminated by a '\n' character. + return p.Flush() +} +``` + +### Tree Formatting + +A common way to represent tree-like structures is the formatting used by the +`tree(1)` unix command. The `textio.TreeWriter` type is an implementation of +an `io.Writer` which supports this kind of output. It works in a recursive +fashion where nodes created from a parent tree writer are formatted as part +of that tree structure. + +Here is an example: +```go +func ls(w io.Writer, path string) { + tree := NewTreeWriter(w) + tree.WriteString(filepath.Base(path)) + defer tree.Close() + + files, _ := ioutil.ReadDir(path) + + for _, f := range files { + if f.Mode().IsDir() { + ls(tree, filepath.Join(path, f.Name())) + } + } + + for _, f := range files { + if !f.Mode().IsDir() { + io.WriteString(NewTreeWriter(tree), f.Name()) + } + } +} + +... + +ls(os.Stdout, "examples") +``` +Which gives this output: +``` +examples +├── A +│ ├── 1 +│ └── 2 +└── message +``` diff --git a/vendor/github.com/segmentio/textio/go.mod b/vendor/github.com/segmentio/textio/go.mod new file mode 100644 index 00000000000..9a1893c961f --- /dev/null +++ b/vendor/github.com/segmentio/textio/go.mod @@ -0,0 +1,3 @@ +module github.com/segmentio/textio + +go 1.12 diff --git a/vendor/github.com/segmentio/textio/io.go b/vendor/github.com/segmentio/textio/io.go new file mode 100644 index 00000000000..e9f2e2b7a02 --- /dev/null +++ b/vendor/github.com/segmentio/textio/io.go @@ -0,0 +1,63 @@ +package textio + +import "io" + +// Base returns the direct base of w, which may be w itself if it had no base +// writer. +func Base(w io.Writer) io.Writer { + if d, ok := w.(decorator); ok { + return coalesceWriters(d.Base(), w) + } + return w +} + +// Root returns the root writer of w, which is found by going up the list of +// base writers. +// +// The node is usually the writer where the content ends up being written. +func Root(w io.Writer) io.Writer { + switch x := w.(type) { + case tree: + return coalesceWriters(x.Root(), w) + case node: + return coalesceWriters(Root(x.Parent()), w) + case decorator: + return coalesceWriters(Root(x.Base()), w) + default: + return w + } +} + +// Parent returns the parent writer of w, which is usually a writer of a similar +// type on tree-like writer structures. +func Parent(w io.Writer) io.Writer { + switch x := w.(type) { + case node: + return coalesceWriters(x.Parent(), w) + case decorator: + return coalesceWriters(Parent(x.Base()), w) + default: + return x + } +} + +type decorator interface { + Base() io.Writer +} + +type node interface { + Parent() io.Writer +} + +type tree interface { + Root() io.Writer +} + +func coalesceWriters(writers ...io.Writer) io.Writer { + for _, w := range writers { + if w != nil { + return w + } + } + return nil +} diff --git a/vendor/github.com/segmentio/textio/prefix.go b/vendor/github.com/segmentio/textio/prefix.go new file mode 100644 index 00000000000..e76fb2eebe6 --- /dev/null +++ b/vendor/github.com/segmentio/textio/prefix.go @@ -0,0 +1,162 @@ +package textio + +import ( + "bytes" + "fmt" + "io" +) + +// PrefixWriter is an implementation of io.Writer which places a prefix before +// every line. +// +// Instances of PrefixWriter are not safe to use concurrently from multiple +// goroutines. +type PrefixWriter struct { + writer io.Writer + indent []byte + buffer []byte + offset int +} + +// NewPrefixWriter constructs a PrefixWriter which outputs to w and prefixes +// every line with s. +func NewPrefixWriter(w io.Writer, s string) *PrefixWriter { + return &PrefixWriter{ + writer: w, + indent: copyStringToBytes(s), + buffer: make([]byte, 0, 256), + } +} + +// Base returns the underlying writer that w outputs to. +func (w *PrefixWriter) Base() io.Writer { + return w.writer +} + +// Buffered returns a byte slice of the data currently buffered in the writer. +func (w *PrefixWriter) Buffered() []byte { + return w.buffer[w.offset:] +} + +// Write writes b to w, satisfies the io.Writer interface. +func (w *PrefixWriter) Write(b []byte) (int, error) { + var c int + var n int + var err error + + forEachLine(b, func(line []byte) bool { + // Always buffer so the input slice doesn't escape and WriteString won't + // copy the string (it saves a dynamic memory allocation on every call + // to WriteString). + w.buffer = append(w.buffer, line...) + + if chunk := w.Buffered(); isLine(chunk) { + c, err = w.writeLine(chunk) + w.discard(c) + } + + n += len(line) + return err == nil + }) + + return n, err +} + +// WriteString writes s to w. +func (w *PrefixWriter) WriteString(s string) (int, error) { + return w.Write([]byte(s)) +} + +// Flush forces all buffered data to be flushed to the underlying writer. +func (w *PrefixWriter) Flush() error { + n, err := w.write(w.buffer) + w.discard(n) + return err +} + +// Width satisfies the fmt.State interface. +func (w *PrefixWriter) Width() (int, bool) { + f, ok := Base(w).(fmt.State) + if ok { + return f.Width() + } + return 0, false +} + +// Precision satisfies the fmt.State interface. +func (w *PrefixWriter) Precision() (int, bool) { + f, ok := Base(w).(fmt.State) + if ok { + return f.Precision() + } + return 0, false +} + +// Flag satisfies the fmt.State interface. +func (w *PrefixWriter) Flag(c int) bool { + f, ok := Base(w).(fmt.State) + if ok { + return f.Flag(c) + } + return false +} + +func (w *PrefixWriter) writeLine(b []byte) (int, error) { + if _, err := w.write(w.indent); err != nil { + return 0, err + } + return w.write(b) +} + +func (w *PrefixWriter) write(b []byte) (int, error) { + return w.writer.Write(b) +} + +func (w *PrefixWriter) discard(n int) { + if n > 0 { + w.offset += n + + switch { + case w.offset == len(w.buffer): + w.buffer = w.buffer[:0] + w.offset = 0 + + case w.offset > (cap(w.buffer) / 2): + copy(w.buffer, w.buffer[w.offset:]) + w.buffer = w.buffer[:len(w.buffer)-w.offset] + w.offset = 0 + } + } +} + +func copyStringToBytes(s string) []byte { + b := make([]byte, len(s)) + copy(b, s) + return b +} + +func forEachLine(b []byte, do func([]byte) bool) { + for len(b) != 0 { + i := bytes.IndexByte(b, '\n') + + if i < 0 { + i = len(b) + } else { + i++ // include the newline character + } + + if !do(b[:i]) { + break + } + + b = b[i:] + } +} + +func isLine(b []byte) bool { + return len(b) != 0 && b[len(b)-1] == '\n' +} + +var ( + _ fmt.State = (*PrefixWriter)(nil) +) diff --git a/vendor/github.com/segmentio/textio/tree.go b/vendor/github.com/segmentio/textio/tree.go new file mode 100644 index 00000000000..d40ee9f0d43 --- /dev/null +++ b/vendor/github.com/segmentio/textio/tree.go @@ -0,0 +1,271 @@ +package textio + +import ( + "bytes" + "fmt" + "io" + "unicode/utf8" +) + +// TreeWriter is an implementation of an io.Writer which prints a tree-like +// representation of the content. +// +// Instances of TreeWriter are not safe to use concurrently from multiple +// goroutines. +type TreeWriter struct { + writer io.Writer + children []*TreeWriter + content []byte +} + +// NewTreeWriter constructs a new TreeWriter which outputs to w. If w is an +// instance of TreeWriter itself the new writer is added to the list of child +// nodes that will be renderend. +func NewTreeWriter(w io.Writer) *TreeWriter { + node := &TreeWriter{ + writer: w, + content: make([]byte, 0, 64), + } + + if parent, _ := node.Parent().(*TreeWriter); parent != nil { + if parent.children == nil { + parent.children = make([]*TreeWriter, 0, 8) + } + parent.children = append(parent.children, node) + } + + return node +} + +// Root returns the root of w, which is the node on which calling Close will +// cause the tree to be rendered to the underlying writer. +func (w *TreeWriter) Root() io.Writer { + if p, _ := w.Parent().(*TreeWriter); p != nil { + return p.Root() + } + return w +} + +// Parent returns the parent node of w, which its most direct base of type +// *TreeWriter. +func (w *TreeWriter) Parent() io.Writer { + if p, _ := w.writer.(*TreeWriter); p != nil { + return p + } + return Parent(w.writer) +} + +// Base returns the base writer of w. +func (w *TreeWriter) Base() io.Writer { + return w.writer +} + +// Write writes b to w, satisfies the io.Writer interface. +func (w *TreeWriter) Write(b []byte) (int, error) { + if w.writer == nil { + return 0, io.ErrClosedPipe + } + w.content = append(w.content, b...) + return len(b), nil +} + +// WriteString writes s to w. +func (w *TreeWriter) WriteString(s string) (int, error) { + return w.Write([]byte(s)) +} + +// WriteByte writes b to w. +func (w *TreeWriter) WriteByte(b byte) error { + w.content = append(w.content, b) + return nil +} + +// WriteRune writes r to w. +func (w *TreeWriter) WriteRune(r rune) (int, error) { + b := [8]byte{} + n := utf8.EncodeRune(b[:], r) + w.content = append(w.content, b[:n]...) + return n, nil +} + +// Width satisfies the fmt.State interface. +func (w *TreeWriter) Width() (int, bool) { + f, ok := Base(w.Root()).(fmt.State) + if ok { + return f.Width() + } + return 0, false +} + +// Precision satisfies the fmt.State interface. +func (w *TreeWriter) Precision() (int, bool) { + f, ok := Base(w.Root()).(fmt.State) + if ok { + return f.Precision() + } + return 0, false +} + +// Flag satisfies the fmt.State interface. +func (w *TreeWriter) Flag(c int) bool { + f, ok := Base(w.Root()).(fmt.State) + if ok { + return f.Flag(c) + } + return false +} + +// Close closes w, causing all buffered content to be flushed to its underlying +// writer, and future write operations to error with io.ErrClosedPipe. +func (w *TreeWriter) Close() (err error) { + defer func() { + w.writer = nil + switch x := recover().(type) { + case nil: + case error: + err = x + default: + err = fmt.Errorf("%+v", x) + } + }() + + // Technically we could have each child node write its own representation + // to a buffer, then render a tree from those content buffers. However this + // would require a lot more copying because each tree level would be written + // into the buffer of its parent. + // + // Instead the approach we take here only requires 1 level of buffering, no + // matter how complex the tree is. First the data is buffered into each node + // and when the tree is closed the code walks through each node and write + // their content and the leading tree symbols to the underlying writer. + + for _, c := range w.children { + if err = c.Close(); err != nil { + return err + } + } + + switch w.writer.(type) { + case nil: + // Already closed + case *TreeWriter: + // Sub-node, don't write anything + default: + buffer := [10]string{} + writer := treeWriter{writer: w.writer, symbols: buffer[:0]} + writer.writeTree(treeCtx{length: 1}, w) + } + + return +} + +var ( + _ io.Writer = (*TreeWriter)(nil) + _ io.StringWriter = (*TreeWriter)(nil) + _ fmt.State = (*TreeWriter)(nil) +) + +type treeCtx struct { + index int // index of the node + length int // number of nodes + needNewLine bool // whether a new line must be printed +} + +func (ctx *treeCtx) last() bool { + return ctx.index == (ctx.length - 1) +} + +type treeWriter struct { + writer io.Writer + symbols []string +} + +func (w *treeWriter) push(ctx treeCtx) { + w.nextLine(ctx) + w.symbols = append(w.symbols, "") +} + +func (w *treeWriter) pop() { + w.symbols = w.symbols[:w.lastIndex()] +} + +func (w *treeWriter) nextNode(ctx treeCtx) { + if ctx.last() { + w.set("└── ") + } else { + w.set("├── ") + } +} + +func (w *treeWriter) nextLine(ctx treeCtx) { + if ctx.last() { + w.set(" ") + } else { + w.set("│ ") + } +} + +func (w *treeWriter) lastIndex() int { + return len(w.symbols) - 1 +} + +func (w *treeWriter) empty() bool { + return len(w.symbols) == 0 +} + +func (w *treeWriter) set(s string) { + if !w.empty() { + w.symbols[w.lastIndex()] = s + } +} + +func (w *treeWriter) writeTree(ctx treeCtx, node *TreeWriter) { + w.writeNode(ctx, node) + w.push(ctx) + + ctx.length = len(node.children) + ctx.needNewLine = !bytes.HasSuffix(node.content, []byte("\n")) + + for i, child := range node.children { + ctx.index = i + w.writeTree(ctx, child) + } + + w.pop() +} + +func (w *treeWriter) writeNode(ctx treeCtx, node *TreeWriter) { + if ctx.needNewLine { + w.writeString("\n") + w.nextLine(ctx) + } + + w.nextNode(ctx) + i := 0 + + forEachLine(node.content, func(line []byte) bool { + if i != 0 { + w.nextLine(ctx) + } + + for _, symbol := range w.symbols { + w.writeString(symbol) + } + + w.write(line) + i++ + return true + }) +} + +func (w *treeWriter) writeString(s string) { + if _, err := io.WriteString(w.writer, s); err != nil { + panic(err) + } +} + +func (w *treeWriter) write(b []byte) { + if _, err := w.writer.Write(b); err != nil { + panic(err) + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index dbf76c9f642..4f80d2c6740 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -255,6 +255,8 @@ github.com/prometheus/procfs/internal/util github.com/rjeczalik/notify # github.com/russross/blackfriday v1.5.2 github.com/russross/blackfriday +# github.com/segmentio/textio v1.2.0 +github.com/segmentio/textio # github.com/sergi/go-diff v1.0.0 github.com/sergi/go-diff/diffmatchpatch # github.com/shurcooL/sanitized_anchor_name v1.0.0 @@ -320,16 +322,16 @@ golang.org/x/net/http2 golang.org/x/net/trace golang.org/x/net/context/ctxhttp golang.org/x/net/proxy +golang.org/x/net/context golang.org/x/net/http/httpguts golang.org/x/net/http2/hpack golang.org/x/net/idna golang.org/x/net/internal/timeseries -golang.org/x/net/context golang.org/x/net/internal/socks # golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 golang.org/x/oauth2 -golang.org/x/oauth2/internal golang.org/x/oauth2/google +golang.org/x/oauth2/internal golang.org/x/oauth2/jws golang.org/x/oauth2/jwt # golang.org/x/sync v0.0.0-20190423024810-112230192c58 @@ -361,16 +363,16 @@ google.golang.org/api/internal google.golang.org/api/googleapi/transport google.golang.org/api/transport/http/internal/propagation # google.golang.org/appengine v1.6.1 +google.golang.org/appengine google.golang.org/appengine/urlfetch google.golang.org/appengine/internal +google.golang.org/appengine/internal/app_identity +google.golang.org/appengine/internal/modules google.golang.org/appengine/internal/urlfetch -google.golang.org/appengine google.golang.org/appengine/internal/base google.golang.org/appengine/internal/datastore google.golang.org/appengine/internal/log google.golang.org/appengine/internal/remote_api -google.golang.org/appengine/internal/app_identity -google.golang.org/appengine/internal/modules # google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610 google.golang.org/genproto/googleapis/api/annotations google.golang.org/genproto/googleapis/iam/v1 @@ -512,6 +514,7 @@ k8s.io/api/storage/v1beta1 # k8s.io/apimachinery v0.0.0-20190620073744-d16981aedf33 k8s.io/apimachinery/pkg/apis/meta/v1 k8s.io/apimachinery/pkg/api/resource +k8s.io/apimachinery/pkg/util/wait k8s.io/apimachinery/pkg/api/meta k8s.io/apimachinery/pkg/runtime k8s.io/apimachinery/pkg/runtime/serializer/json @@ -522,7 +525,6 @@ k8s.io/apimachinery/pkg/util/yaml k8s.io/apimachinery/pkg/api/errors k8s.io/apimachinery/pkg/fields k8s.io/apimachinery/pkg/watch -k8s.io/apimachinery/pkg/util/wait k8s.io/apimachinery/pkg/labels k8s.io/apimachinery/pkg/util/intstr k8s.io/apimachinery/pkg/conversion From 5013752460170ed0b8f18fbcf5b590a76560aa1b Mon Sep 17 00:00:00 2001 From: David Gageot Date: Thu, 29 Aug 2019 21:46:56 +0200 Subject: [PATCH 63/69] Validate image names when config is read (#2755) See #2528 Signed-off-by: David Gageot --- pkg/skaffold/schema/validation/validation.go | 23 +++ .../schema/validation/validation_test.go | 160 ++++++++++++------ 2 files changed, 132 insertions(+), 51 deletions(-) diff --git a/pkg/skaffold/schema/validation/validation.go b/pkg/skaffold/schema/validation/validation.go index 91b2a7785a7..b1a477b7cb0 100644 --- a/pkg/skaffold/schema/validation/validation.go +++ b/pkg/skaffold/schema/validation/validation.go @@ -21,6 +21,7 @@ import ( "reflect" "strings" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/yamltags" ) @@ -33,6 +34,7 @@ var ( // Process checks if the Skaffold pipeline is valid and returns all encountered errors as a concatenated string func Process(config *latest.SkaffoldConfig) error { errs := visitStructs(config, validateYamltags) + errs = append(errs, validateImageNames(config.Build.Artifacts)...) errs = append(errs, validateDockerNetworkMode(config.Build.Artifacts)...) errs = append(errs, validateCustomDependencies(config.Build.Artifacts)...) errs = append(errs, validateSyncRules(config.Build.Artifacts)...) @@ -49,6 +51,27 @@ func Process(config *latest.SkaffoldConfig) error { return fmt.Errorf(strings.Join(messages, " | ")) } +// validateImageNames makes sure the artifact image names are valid base names, +// without tags nor digests. +func validateImageNames(artifacts []*latest.Artifact) (errs []error) { + for _, a := range artifacts { + parsed, err := docker.ParseReference(a.ImageName) + if err != nil { + errs = append(errs, fmt.Errorf("invalid imageName '%s': %v", a.ImageName, err)) + continue + } + + if parsed.Tag != "" { + errs = append(errs, fmt.Errorf("invalid imageName '%s': no tag should be specified. Use taggers instead: https://skaffold.dev/docs/how-tos/taggers/", a.ImageName)) + } + + if parsed.Digest != "" { + errs = append(errs, fmt.Errorf("invalid imageName '%s': no digest should be specified. Use taggers instead: https://skaffold.dev/docs/how-tos/taggers/", a.ImageName)) + } + } + return +} + // validateDockerNetworkMode makes sure that networkMode is one of `bridge`, `none`, or `host` if set. func validateDockerNetworkMode(artifacts []*latest.Artifact) (errs []error) { for _, a := range artifacts { diff --git a/pkg/skaffold/schema/validation/validation_test.go b/pkg/skaffold/schema/validation/validation_test.go index 9aecbfc69cc..cc7cd01c834 100644 --- a/pkg/skaffold/schema/validation/validation_test.go +++ b/pkg/skaffold/schema/validation/validation_test.go @@ -377,72 +377,69 @@ func TestValidateSyncRules(t *testing.T) { }, { description: "no sync rules", - artifacts: []*latest.Artifact{ - { - Sync: nil, - }, - }, + artifacts: []*latest.Artifact{{ + ImageName: "img", + Sync: nil, + }}, }, { description: "two good rules", - artifacts: []*latest.Artifact{ - { - Sync: &latest.Sync{Manual: []*latest.SyncRule{ - { - Src: "src/**/*.js", - Dest: ".", - }, - { - Src: "src/**/*.js", - Dest: ".", - Strip: "src/", - }, - }}, - }, - }, + artifacts: []*latest.Artifact{{ + ImageName: "img", + Sync: &latest.Sync{Manual: []*latest.SyncRule{ + { + Src: "src/**/*.js", + Dest: ".", + }, + { + Src: "src/**/*.js", + Dest: ".", + Strip: "src/", + }, + }}, + }}, }, { description: "one good one bad rule", - artifacts: []*latest.Artifact{ - { - Sync: &latest.Sync{Manual: []*latest.SyncRule{ - { - Src: "src/**/*.js", - Dest: ".", - Strip: "/src", - }, - { - Src: "src/**/*.py", - Dest: ".", - Strip: "src/", - }, - }}, - }, - }, + artifacts: []*latest.Artifact{{ + ImageName: "img", + Sync: &latest.Sync{Manual: []*latest.SyncRule{ + { + Src: "src/**/*.js", + Dest: ".", + Strip: "/src", + }, + { + Src: "src/**/*.py", + Dest: ".", + Strip: "src/", + }, + }}, + }}, shouldErr: true, }, { description: "two bad rules", - artifacts: []*latest.Artifact{ - { - Sync: &latest.Sync{Manual: []*latest.SyncRule{ - { - Dest: ".", - Strip: "src", - }, - { - Src: "**/*.js", - Dest: ".", - Strip: "src/", - }, - }}, - }, - }, + artifacts: []*latest.Artifact{{ + ImageName: "img", + Sync: &latest.Sync{Manual: []*latest.SyncRule{ + { + Dest: ".", + Strip: "src", + }, + { + Src: "**/*.js", + Dest: ".", + Strip: "src/", + }, + }}, + }}, shouldErr: true, }, { description: "stripping part of folder name is valid", artifacts: []*latest.Artifact{{ + ImageName: "img", Sync: &latest.Sync{ Manual: []*latest.SyncRule{{ Src: "srcsomeother/**/*.js", @@ -555,3 +552,64 @@ func TestValidatePortForwardResources(t *testing.T) { }) } } + +func TestValidateImageNames(t *testing.T) { + tests := []struct { + description string + artifacts []*latest.Artifact + shouldErr bool + }{ + { + description: "no name", + artifacts: []*latest.Artifact{{ + ImageName: "", + }}, + shouldErr: true, + }, + { + description: "valid", + artifacts: []*latest.Artifact{{ + ImageName: "img", + }}, + shouldErr: false, + }, + { + description: "shouldn't have a tag", + artifacts: []*latest.Artifact{{ + ImageName: "img:tag", + }}, + shouldErr: true, + }, + { + description: "shouldn't have a digest", + artifacts: []*latest.Artifact{{ + ImageName: "img@sha256:77af4d6b9913e693e8d0b4b294fa62ade6054e6b2f1ffb617ac955dd63fb0182", + }}, + shouldErr: true, + }, + { + description: "no tag nor digest", + artifacts: []*latest.Artifact{{ + ImageName: "img:tag@sha256:77af4d6b9913e693e8d0b4b294fa62ade6054e6b2f1ffb617ac955dd63fb0182", + }}, + shouldErr: true, + }, + } + for _, test := range tests { + testutil.Run(t, test.description, func(t *testutil.T) { + // disable yamltags validation + t.Override(&validateYamltags, func(interface{}) error { return nil }) + + err := Process( + &latest.SkaffoldConfig{ + Pipeline: latest.Pipeline{ + Build: latest.BuildConfig{ + Artifacts: test.artifacts, + }, + }, + }) + + t.CheckError(test.shouldErr, err) + }) + } +} From a7f3b375aba94bfa573ffd9cdad88910bd48d083 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Thu, 29 Aug 2019 21:47:41 +0200 Subject: [PATCH 64/69] Apply port forward config from profiles (#2754) Fixes #2733 Signed-off-by: David Gageot --- pkg/skaffold/schema/profiles.go | 22 +++++++++++-------- pkg/skaffold/schema/profiles_test.go | 33 ++++++++++++++++++++++++++++ pkg/skaffold/schema/versions_test.go | 6 +++++ 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/pkg/skaffold/schema/profiles.go b/pkg/skaffold/schema/profiles.go index 55c4f171aa7..19060f5033f 100644 --- a/pkg/skaffold/schema/profiles.go +++ b/pkg/skaffold/schema/profiles.go @@ -149,17 +149,21 @@ func matches(expected, actual string) bool { func applyProfile(config *latest.SkaffoldConfig, profile latest.Profile) error { logrus.Infof("applying profile: %s", profile.Name) - // this intentionally removes the Profiles field from the returned config - *config = latest.SkaffoldConfig{ - APIVersion: config.APIVersion, - Kind: config.Kind, - Pipeline: latest.Pipeline{ - Build: overlayProfileField("build", config.Build, profile.Build).(latest.BuildConfig), - Deploy: overlayProfileField("deploy", config.Deploy, profile.Deploy).(latest.DeployConfig), - Test: overlayProfileField("test", config.Test, profile.Test).([]*latest.TestCase), - }, + // Apply profile, field by field + mergedV := reflect.Indirect(reflect.ValueOf(&config.Pipeline)) + configV := reflect.ValueOf(config.Pipeline) + profileV := reflect.ValueOf(profile.Pipeline) + + profileT := profileV.Type() + for i := 0; i < profileT.NumField(); i++ { + name := profileT.Field(i).Name + merged := overlayProfileField(name, configV.FieldByName(name).Interface(), profileV.FieldByName(name).Interface()) + mergedV.FieldByName(name).Set(reflect.ValueOf(merged)) } + // Remove the Profiles field from the returned config + config.Profiles = nil + if len(profile.Patches) == 0 { return nil } diff --git a/pkg/skaffold/schema/profiles_test.go b/pkg/skaffold/schema/profiles_test.go index 0a7b457a215..fd1866153b9 100644 --- a/pkg/skaffold/schema/profiles_test.go +++ b/pkg/skaffold/schema/profiles_test.go @@ -303,6 +303,39 @@ func TestApplyProfiles(t *testing.T) { }), ), }, + { + description: "port forwarding", + profile: "profile", + config: config( + withLocalBuild( + withGitTagger(), + ), + withProfiles(latest.Profile{ + Name: "profile", + Pipeline: latest.Pipeline{ + PortForward: []*latest.PortForwardResource{{ + Namespace: "ns", + Name: "name", + Type: "service", + Port: 8080, + LocalPort: 8888, + }}, + }, + }), + ), + expected: config( + withLocalBuild( + withGitTagger(), + ), + withPortForward(&latest.PortForwardResource{ + Namespace: "ns", + Name: "name", + Type: "service", + Port: 8080, + LocalPort: 8888, + }), + ), + }, } for _, test := range tests { testutil.Run(t, test.description, func(t *testutil.T) { diff --git a/pkg/skaffold/schema/versions_test.go b/pkg/skaffold/schema/versions_test.go index cf116c5bf7d..66a2a475978 100644 --- a/pkg/skaffold/schema/versions_test.go +++ b/pkg/skaffold/schema/versions_test.go @@ -405,6 +405,12 @@ func withTests(testCases ...*latest.TestCase) func(*latest.SkaffoldConfig) { } } +func withPortForward(portForward ...*latest.PortForwardResource) func(*latest.SkaffoldConfig) { + return func(cfg *latest.SkaffoldConfig) { + cfg.PortForward = portForward + } +} + func withStatusCheckDeadline(deadline int) func(*latest.SkaffoldConfig) { return func(cfg *latest.SkaffoldConfig) { cfg.Deploy.StatusCheckDeadlineSeconds = deadline From e5be3954c1fb41dff98943f8da05e921050edc49 Mon Sep 17 00:00:00 2001 From: balopat Date: Thu, 29 Aug 2019 13:57:24 -0700 Subject: [PATCH 65/69] npm audit fix on examples --- examples/nodejs/backend/package-lock.json | 899 +++++++++--------- examples/nodejs/backend/package.json | 2 +- .../examples/nodejs/backend/package-lock.json | 899 +++++++++--------- .../examples/nodejs/backend/package.json | 2 +- 4 files changed, 904 insertions(+), 898 deletions(-) diff --git a/examples/nodejs/backend/package-lock.json b/examples/nodejs/backend/package-lock.json index a3ae06edb4d..32f0279a77b 100644 --- a/examples/nodejs/backend/package-lock.json +++ b/examples/nodejs/backend/package-lock.json @@ -15,7 +15,7 @@ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "requires": { - "mime-types": "2.1.21", + "mime-types": "~2.1.18", "negotiator": "0.6.1" } }, @@ -25,7 +25,7 @@ "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", "dev": true, "requires": { - "string-width": "2.1.1" + "string-width": "^2.0.0" } }, "ansi-regex": { @@ -40,7 +40,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.3" + "color-convert": "^1.9.0" } }, "anymatch": { @@ -49,8 +49,8 @@ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "micromatch": "3.1.10", - "normalize-path": "2.1.1" + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" } }, "arr-diff": { @@ -112,13 +112,13 @@ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { - "cache-base": "1.0.1", - "class-utils": "0.3.6", - "component-emitter": "1.2.1", - "define-property": "1.0.0", - "isobject": "3.0.1", - "mixin-deep": "1.3.1", - "pascalcase": "0.1.1" + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" }, "dependencies": { "define-property": { @@ -127,7 +127,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -136,7 +136,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -145,7 +145,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -154,9 +154,28 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" } } } @@ -173,15 +192,15 @@ "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", "requires": { "bytes": "3.0.0", - "content-type": "1.0.4", + "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "1.1.2", - "http-errors": "1.6.3", + "depd": "~1.1.2", + "http-errors": "~1.6.3", "iconv-lite": "0.4.23", - "on-finished": "2.3.0", + "on-finished": "~2.3.0", "qs": "6.5.2", "raw-body": "2.3.3", - "type-is": "1.6.16" + "type-is": "~1.6.16" } }, "boxen": { @@ -190,13 +209,13 @@ "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", "dev": true, "requires": { - "ansi-align": "2.0.0", - "camelcase": "4.1.0", - "chalk": "2.4.1", - "cli-boxes": "1.0.0", - "string-width": "2.1.1", - "term-size": "1.2.0", - "widest-line": "2.0.1" + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" } }, "brace-expansion": { @@ -205,7 +224,7 @@ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -215,16 +234,16 @@ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "repeat-element": "1.1.3", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -233,7 +252,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -249,15 +268,64 @@ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { - "collection-visit": "1.0.0", - "component-emitter": "1.2.1", - "get-value": "2.0.6", - "has-value": "1.0.0", - "isobject": "3.0.1", - "set-value": "2.0.0", - "to-object-path": "0.3.0", - "union-value": "1.0.0", - "unset-value": "1.0.0" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + } + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + } } }, "camelcase": { @@ -278,30 +346,9 @@ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.5.0" - } - }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "dev": true, - "requires": { - "anymatch": "2.0.0", - "async-each": "1.0.1", - "braces": "2.3.2", - "fsevents": "1.2.4", - "glob-parent": "3.1.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "4.0.0", - "lodash.debounce": "4.0.8", - "normalize-path": "2.1.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.2.1", - "upath": "1.1.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "ci-info": { @@ -316,10 +363,10 @@ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { - "arr-union": "3.1.0", - "define-property": "0.2.5", - "isobject": "3.0.1", - "static-extend": "0.1.2" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, "dependencies": { "define-property": { @@ -328,7 +375,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -345,8 +392,8 @@ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { - "map-visit": "1.0.0", - "object-visit": "1.0.1" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, "color-convert": { @@ -382,12 +429,12 @@ "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", "dev": true, "requires": { - "dot-prop": "4.2.0", - "graceful-fs": "4.1.15", - "make-dir": "1.3.0", - "unique-string": "1.0.0", - "write-file-atomic": "2.3.0", - "xdg-basedir": "3.0.0" + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" } }, "content-disposition": { @@ -428,7 +475,7 @@ "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", "dev": true, "requires": { - "capture-stack-trace": "1.0.1" + "capture-stack-trace": "^1.0.0" } }, "cross-spawn": { @@ -437,9 +484,9 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "4.1.4", - "shebang-command": "1.2.0", - "which": "1.3.1" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "crypto-random-string": { @@ -474,8 +521,8 @@ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { - "is-descriptor": "1.0.2", - "isobject": "3.0.1" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "dependencies": { "is-accessor-descriptor": { @@ -484,7 +531,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -493,7 +540,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -502,9 +549,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -525,7 +572,7 @@ "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", "dev": true, "requires": { - "is-obj": "1.0.1" + "is-obj": "^1.0.0" } }, "duplexer3": { @@ -566,13 +613,13 @@ "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "dev": true, "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" } }, "expand-brackets": { @@ -581,13 +628,13 @@ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -596,7 +643,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -605,7 +652,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -615,36 +662,36 @@ "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", "requires": { - "accepts": "1.3.5", + "accepts": "~1.3.5", "array-flatten": "1.1.1", "body-parser": "1.18.3", "content-disposition": "0.5.2", - "content-type": "1.0.4", + "content-type": "~1.0.4", "cookie": "0.3.1", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "1.1.2", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "finalhandler": "1.1.1", "fresh": "0.5.2", "merge-descriptors": "1.0.1", - "methods": "1.1.2", - "on-finished": "2.3.0", - "parseurl": "1.3.2", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", "path-to-regexp": "0.1.7", - "proxy-addr": "2.0.4", + "proxy-addr": "~2.0.4", "qs": "6.5.2", - "range-parser": "1.2.0", + "range-parser": "~1.2.0", "safe-buffer": "5.1.2", "send": "0.16.2", "serve-static": "1.13.2", "setprototypeof": "1.1.0", - "statuses": "1.4.0", - "type-is": "1.6.16", + "statuses": "~1.4.0", + "type-is": "~1.6.16", "utils-merge": "1.0.1", - "vary": "1.1.2" + "vary": "~1.1.2" } }, "extend-shallow": { @@ -653,8 +700,8 @@ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { - "assign-symbols": "1.0.0", - "is-extendable": "1.0.1" + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -663,7 +710,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -674,14 +721,14 @@ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -690,7 +737,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "extend-shallow": { @@ -699,7 +746,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "is-accessor-descriptor": { @@ -708,7 +755,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -717,7 +764,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -726,9 +773,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -739,10 +786,10 @@ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "dependencies": { "extend-shallow": { @@ -751,7 +798,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -762,12 +809,12 @@ "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "requires": { "debug": "2.6.9", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "statuses": "1.4.0", - "unpipe": "1.0.0" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" } }, "for-in": { @@ -787,7 +834,7 @@ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { - "map-cache": "0.2.2" + "map-cache": "^0.2.2" } }, "fresh": { @@ -802,8 +849,8 @@ "dev": true, "optional": true, "requires": { - "nan": "2.11.1", - "node-pre-gyp": "0.10.0" + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" }, "dependencies": { "abbrev": { @@ -836,12 +883,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "1.0.0", "concat-map": "0.0.1" @@ -856,17 +905,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -983,7 +1035,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -995,6 +1048,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "1.0.1" } @@ -1009,6 +1063,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "1.1.11" } @@ -1016,12 +1071,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "5.1.1", "yallist": "3.0.2" @@ -1040,6 +1097,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -1120,7 +1178,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -1132,6 +1191,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1.0.2" } @@ -1253,6 +1313,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "1.1.0", "is-fullwidth-code-point": "1.0.0", @@ -1342,8 +1403,8 @@ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" }, "dependencies": { "is-glob": { @@ -1352,7 +1413,7 @@ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.0" } } } @@ -1363,7 +1424,7 @@ "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", "dev": true, "requires": { - "ini": "1.3.5" + "ini": "^1.3.4" } }, "got": { @@ -1372,17 +1433,17 @@ "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", "dev": true, "requires": { - "create-error-class": "3.0.2", - "duplexer3": "0.1.4", - "get-stream": "3.0.0", - "is-redirect": "1.0.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "lowercase-keys": "1.0.1", - "safe-buffer": "5.1.2", - "timed-out": "4.0.1", - "unzip-response": "2.0.1", - "url-parse-lax": "1.0.0" + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" } }, "graceful-fs": { @@ -1403,9 +1464,9 @@ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "1.0.0", - "isobject": "3.0.1" + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" } }, "has-values": { @@ -1414,8 +1475,8 @@ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "dependencies": { "kind-of": { @@ -1424,7 +1485,7 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1434,10 +1495,10 @@ "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "requires": { - "depd": "1.1.2", + "depd": "~1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.0", - "statuses": "1.4.0" + "statuses": ">= 1.4.0 < 2" } }, "iconv-lite": { @@ -1445,7 +1506,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore-by-default": { @@ -1488,7 +1549,7 @@ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -1497,7 +1558,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1508,7 +1569,7 @@ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "1.12.0" + "binary-extensions": "^1.0.0" } }, "is-buffer": { @@ -1523,7 +1584,7 @@ "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", "dev": true, "requires": { - "ci-info": "1.6.0" + "ci-info": "^1.5.0" } }, "is-data-descriptor": { @@ -1532,7 +1593,7 @@ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -1541,7 +1602,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1552,9 +1613,9 @@ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" }, "dependencies": { "kind-of": { @@ -1589,7 +1650,7 @@ "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.1" } }, "is-installed-globally": { @@ -1598,8 +1659,8 @@ "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", "dev": true, "requires": { - "global-dirs": "0.1.1", - "is-path-inside": "1.0.1" + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" } }, "is-npm": { @@ -1614,7 +1675,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -1623,7 +1684,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1640,7 +1701,7 @@ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "dev": true, "requires": { - "path-is-inside": "1.0.2" + "path-is-inside": "^1.0.1" } }, "is-plain-object": { @@ -1649,7 +1710,7 @@ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" } }, "is-redirect": { @@ -1706,7 +1767,7 @@ "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", "dev": true, "requires": { - "package-json": "4.0.1" + "package-json": "^4.0.0" } }, "lodash.debounce": { @@ -1727,8 +1788,8 @@ "integrity": "sha512-EPstzZ23znHUVLKj+lcXO1KvZkrlw+ZirdwvOmnAnA/1PB4ggyXJ77LRkCqkff+ShQ+cqoxCxLQOh4cKITO5iA==", "dev": true, "requires": { - "pseudomap": "1.0.2", - "yallist": "3.0.3" + "pseudomap": "^1.0.2", + "yallist": "^3.0.2" } }, "make-dir": { @@ -1737,7 +1798,7 @@ "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, "requires": { - "pify": "3.0.0" + "pify": "^3.0.0" } }, "map-cache": { @@ -1752,7 +1813,7 @@ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { - "object-visit": "1.0.1" + "object-visit": "^1.0.0" } }, "media-typer": { @@ -1776,19 +1837,19 @@ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.13", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } }, "mime": { @@ -1806,7 +1867,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", "requires": { - "mime-db": "1.37.0" + "mime-db": "~1.37.0" } }, "minimatch": { @@ -1815,7 +1876,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -1824,27 +1885,6 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, - "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", - "dev": true, - "requires": { - "for-in": "1.0.2", - "is-extendable": "1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "2.0.4" - } - } - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -1863,17 +1903,17 @@ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "fragment-cache": "0.2.1", - "is-windows": "1.0.2", - "kind-of": "6.0.2", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" } }, "negotiator": { @@ -1887,25 +1927,46 @@ "integrity": "sha512-xuC1V0F5EcEyKQ1VhHYD13owznQbUw29JKvZ8bVH7TmuvVNHvvbp9pLgE4PjTMRJVe0pJ8fGRvwR2nMiosIsPQ==", "dev": true, "requires": { - "chokidar": "2.0.4", - "debug": "3.2.6", - "ignore-by-default": "1.0.1", - "minimatch": "3.0.4", - "pstree.remy": "1.1.2", - "semver": "5.6.0", - "supports-color": "5.5.0", - "touch": "3.1.0", - "undefsafe": "2.0.2", - "update-notifier": "2.5.0" + "chokidar": "^2.0.4", + "debug": "^3.1.0", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.2", + "semver": "^5.5.0", + "supports-color": "^5.2.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.2", + "update-notifier": "^2.3.0" }, "dependencies": { + "chokidar": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.0", + "braces": "^2.3.0", + "fsevents": "^1.2.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "lodash.debounce": "^4.0.8", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0", + "upath": "^1.0.5" + } + }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "ms": { @@ -1922,7 +1983,7 @@ "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", "dev": true, "requires": { - "abbrev": "1.1.1" + "abbrev": "1" } }, "normalize-path": { @@ -1931,7 +1992,7 @@ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { - "remove-trailing-separator": "1.1.0" + "remove-trailing-separator": "^1.0.1" } }, "npm-run-path": { @@ -1940,7 +2001,7 @@ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, "requires": { - "path-key": "2.0.1" + "path-key": "^2.0.0" } }, "object-copy": { @@ -1949,9 +2010,9 @@ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { - "copy-descriptor": "0.1.1", - "define-property": "0.2.5", - "kind-of": "3.2.2" + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" }, "dependencies": { "define-property": { @@ -1960,7 +2021,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "kind-of": { @@ -1969,7 +2030,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1980,7 +2041,7 @@ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.0" } }, "object.pick": { @@ -1989,7 +2050,7 @@ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" } }, "on-finished": { @@ -2012,10 +2073,10 @@ "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", "dev": true, "requires": { - "got": "6.7.1", - "registry-auth-token": "3.3.2", - "registry-url": "3.1.0", - "semver": "5.6.0" + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" } }, "parseurl": { @@ -2087,7 +2148,7 @@ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", "requires": { - "forwarded": "0.1.2", + "forwarded": "~0.1.2", "ipaddr.js": "1.8.0" } }, @@ -2130,10 +2191,10 @@ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, "requires": { - "deep-extend": "0.6.0", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" } }, "readable-stream": { @@ -2142,13 +2203,13 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "readdirp": { @@ -2157,9 +2218,9 @@ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "micromatch": "3.1.10", - "readable-stream": "2.3.6" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" } }, "regex-not": { @@ -2168,8 +2229,8 @@ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "requires": { - "extend-shallow": "3.0.2", - "safe-regex": "1.1.0" + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" } }, "registry-auth-token": { @@ -2178,8 +2239,8 @@ "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", "dev": true, "requires": { - "rc": "1.2.8", - "safe-buffer": "5.1.2" + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" } }, "registry-url": { @@ -2188,7 +2249,7 @@ "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", "dev": true, "requires": { - "rc": "1.2.8" + "rc": "^1.0.1" } }, "remove-trailing-separator": { @@ -2232,7 +2293,7 @@ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { - "ret": "0.1.15" + "ret": "~0.1.10" } }, "safer-buffer": { @@ -2252,7 +2313,7 @@ "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", "dev": true, "requires": { - "semver": "5.6.0" + "semver": "^5.0.3" } }, "send": { @@ -2261,18 +2322,18 @@ "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", "requires": { "debug": "2.6.9", - "depd": "1.1.2", - "destroy": "1.0.4", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.6.3", + "http-errors": "~1.6.2", "mime": "1.4.1", "ms": "2.0.0", - "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.4.0" + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" } }, "serve-static": { @@ -2280,35 +2341,12 @@ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", "requires": { - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "parseurl": "1.3.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", "send": "0.16.2" } }, - "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "dev": true, - "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "split-string": "3.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } - } - }, "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", @@ -2320,7 +2358,7 @@ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { - "shebang-regex": "1.0.0" + "shebang-regex": "^1.0.0" } }, "shebang-regex": { @@ -2341,14 +2379,14 @@ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { - "base": "0.11.2", - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "map-cache": "0.2.2", - "source-map": "0.5.7", - "source-map-resolve": "0.5.2", - "use": "3.1.1" + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" }, "dependencies": { "define-property": { @@ -2357,7 +2395,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -2366,7 +2404,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -2377,9 +2415,9 @@ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "requires": { - "define-property": "1.0.0", - "isobject": "3.0.1", - "snapdragon-util": "3.0.1" + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" }, "dependencies": { "define-property": { @@ -2388,7 +2426,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -2397,7 +2435,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -2406,7 +2444,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -2415,9 +2453,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -2428,7 +2466,7 @@ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.2.0" }, "dependencies": { "kind-of": { @@ -2437,7 +2475,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -2454,11 +2492,11 @@ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "dev": true, "requires": { - "atob": "2.1.2", - "decode-uri-component": "0.2.0", - "resolve-url": "0.2.1", - "source-map-url": "0.4.0", - "urix": "0.1.0" + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" } }, "source-map-url": { @@ -2473,7 +2511,7 @@ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "requires": { - "extend-shallow": "3.0.2" + "extend-shallow": "^3.0.0" } }, "static-extend": { @@ -2482,8 +2520,8 @@ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { - "define-property": "0.2.5", - "object-copy": "0.1.0" + "define-property": "^0.2.5", + "object-copy": "^0.1.0" }, "dependencies": { "define-property": { @@ -2492,7 +2530,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -2508,8 +2546,8 @@ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" } }, "string_decoder": { @@ -2518,7 +2556,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { @@ -2527,7 +2565,7 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } }, "strip-eof": { @@ -2548,7 +2586,7 @@ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } }, "term-size": { @@ -2557,7 +2595,7 @@ "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", "dev": true, "requires": { - "execa": "0.7.0" + "execa": "^0.7.0" } }, "timed-out": { @@ -2572,7 +2610,7 @@ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -2581,7 +2619,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -2592,10 +2630,10 @@ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "regex-not": "1.0.2", - "safe-regex": "1.1.0" + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" } }, "to-regex-range": { @@ -2604,8 +2642,8 @@ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { - "is-number": "3.0.0", - "repeat-string": "1.6.1" + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" } }, "touch": { @@ -2614,7 +2652,7 @@ "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", "dev": true, "requires": { - "nopt": "1.0.10" + "nopt": "~1.0.10" } }, "type-is": { @@ -2623,7 +2661,7 @@ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", "requires": { "media-typer": "0.3.0", - "mime-types": "2.1.21" + "mime-types": "~2.1.18" } }, "undefsafe": { @@ -2632,42 +2670,7 @@ "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", "dev": true, "requires": { - "debug": "2.6.9" - } - }, - "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "dev": true, - "requires": { - "arr-union": "3.1.0", - "get-value": "2.0.6", - "is-extendable": "0.1.1", - "set-value": "0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "to-object-path": "0.3.0" - } - } + "debug": "^2.2.0" } }, "unique-string": { @@ -2676,7 +2679,7 @@ "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", "dev": true, "requires": { - "crypto-random-string": "1.0.0" + "crypto-random-string": "^1.0.0" } }, "unpipe": { @@ -2690,8 +2693,8 @@ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { - "has-value": "0.3.1", - "isobject": "3.0.1" + "has-value": "^0.3.1", + "isobject": "^3.0.0" }, "dependencies": { "has-value": { @@ -2700,9 +2703,9 @@ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "0.1.4", - "isobject": "2.1.0" + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" }, "dependencies": { "isobject": { @@ -2742,16 +2745,16 @@ "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", "dev": true, "requires": { - "boxen": "1.3.0", - "chalk": "2.4.1", - "configstore": "3.1.2", - "import-lazy": "2.1.0", - "is-ci": "1.2.1", - "is-installed-globally": "0.1.0", - "is-npm": "1.0.0", - "latest-version": "3.1.0", - "semver-diff": "2.1.0", - "xdg-basedir": "3.0.0" + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" } }, "urix": { @@ -2766,7 +2769,7 @@ "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", "dev": true, "requires": { - "prepend-http": "1.0.4" + "prepend-http": "^1.0.1" } }, "use": { @@ -2797,7 +2800,7 @@ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { - "isexe": "2.0.0" + "isexe": "^2.0.0" } }, "widest-line": { @@ -2806,7 +2809,7 @@ "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", "dev": true, "requires": { - "string-width": "2.1.1" + "string-width": "^2.1.1" } }, "write-file-atomic": { @@ -2815,9 +2818,9 @@ "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "imurmurhash": "0.1.4", - "signal-exit": "3.0.2" + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" } }, "xdg-basedir": { diff --git a/examples/nodejs/backend/package.json b/examples/nodejs/backend/package.json index 66ddb0badf3..843517e9b4f 100644 --- a/examples/nodejs/backend/package.json +++ b/examples/nodejs/backend/package.json @@ -12,4 +12,4 @@ "devDependencies": { "nodemon": "^1.18.4" } -} \ No newline at end of file +} diff --git a/integration/examples/nodejs/backend/package-lock.json b/integration/examples/nodejs/backend/package-lock.json index a3ae06edb4d..32f0279a77b 100644 --- a/integration/examples/nodejs/backend/package-lock.json +++ b/integration/examples/nodejs/backend/package-lock.json @@ -15,7 +15,7 @@ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "requires": { - "mime-types": "2.1.21", + "mime-types": "~2.1.18", "negotiator": "0.6.1" } }, @@ -25,7 +25,7 @@ "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", "dev": true, "requires": { - "string-width": "2.1.1" + "string-width": "^2.0.0" } }, "ansi-regex": { @@ -40,7 +40,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.3" + "color-convert": "^1.9.0" } }, "anymatch": { @@ -49,8 +49,8 @@ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "micromatch": "3.1.10", - "normalize-path": "2.1.1" + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" } }, "arr-diff": { @@ -112,13 +112,13 @@ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { - "cache-base": "1.0.1", - "class-utils": "0.3.6", - "component-emitter": "1.2.1", - "define-property": "1.0.0", - "isobject": "3.0.1", - "mixin-deep": "1.3.1", - "pascalcase": "0.1.1" + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" }, "dependencies": { "define-property": { @@ -127,7 +127,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -136,7 +136,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -145,7 +145,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -154,9 +154,28 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" } } } @@ -173,15 +192,15 @@ "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", "requires": { "bytes": "3.0.0", - "content-type": "1.0.4", + "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "1.1.2", - "http-errors": "1.6.3", + "depd": "~1.1.2", + "http-errors": "~1.6.3", "iconv-lite": "0.4.23", - "on-finished": "2.3.0", + "on-finished": "~2.3.0", "qs": "6.5.2", "raw-body": "2.3.3", - "type-is": "1.6.16" + "type-is": "~1.6.16" } }, "boxen": { @@ -190,13 +209,13 @@ "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", "dev": true, "requires": { - "ansi-align": "2.0.0", - "camelcase": "4.1.0", - "chalk": "2.4.1", - "cli-boxes": "1.0.0", - "string-width": "2.1.1", - "term-size": "1.2.0", - "widest-line": "2.0.1" + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" } }, "brace-expansion": { @@ -205,7 +224,7 @@ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -215,16 +234,16 @@ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "repeat-element": "1.1.3", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -233,7 +252,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -249,15 +268,64 @@ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { - "collection-visit": "1.0.0", - "component-emitter": "1.2.1", - "get-value": "2.0.6", - "has-value": "1.0.0", - "isobject": "3.0.1", - "set-value": "2.0.0", - "to-object-path": "0.3.0", - "union-value": "1.0.0", - "unset-value": "1.0.0" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + } + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + } } }, "camelcase": { @@ -278,30 +346,9 @@ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.5.0" - } - }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "dev": true, - "requires": { - "anymatch": "2.0.0", - "async-each": "1.0.1", - "braces": "2.3.2", - "fsevents": "1.2.4", - "glob-parent": "3.1.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "4.0.0", - "lodash.debounce": "4.0.8", - "normalize-path": "2.1.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.2.1", - "upath": "1.1.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "ci-info": { @@ -316,10 +363,10 @@ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { - "arr-union": "3.1.0", - "define-property": "0.2.5", - "isobject": "3.0.1", - "static-extend": "0.1.2" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, "dependencies": { "define-property": { @@ -328,7 +375,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -345,8 +392,8 @@ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { - "map-visit": "1.0.0", - "object-visit": "1.0.1" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, "color-convert": { @@ -382,12 +429,12 @@ "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", "dev": true, "requires": { - "dot-prop": "4.2.0", - "graceful-fs": "4.1.15", - "make-dir": "1.3.0", - "unique-string": "1.0.0", - "write-file-atomic": "2.3.0", - "xdg-basedir": "3.0.0" + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" } }, "content-disposition": { @@ -428,7 +475,7 @@ "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", "dev": true, "requires": { - "capture-stack-trace": "1.0.1" + "capture-stack-trace": "^1.0.0" } }, "cross-spawn": { @@ -437,9 +484,9 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "4.1.4", - "shebang-command": "1.2.0", - "which": "1.3.1" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "crypto-random-string": { @@ -474,8 +521,8 @@ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { - "is-descriptor": "1.0.2", - "isobject": "3.0.1" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "dependencies": { "is-accessor-descriptor": { @@ -484,7 +531,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -493,7 +540,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -502,9 +549,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -525,7 +572,7 @@ "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", "dev": true, "requires": { - "is-obj": "1.0.1" + "is-obj": "^1.0.0" } }, "duplexer3": { @@ -566,13 +613,13 @@ "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "dev": true, "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" } }, "expand-brackets": { @@ -581,13 +628,13 @@ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -596,7 +643,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -605,7 +652,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -615,36 +662,36 @@ "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", "requires": { - "accepts": "1.3.5", + "accepts": "~1.3.5", "array-flatten": "1.1.1", "body-parser": "1.18.3", "content-disposition": "0.5.2", - "content-type": "1.0.4", + "content-type": "~1.0.4", "cookie": "0.3.1", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "1.1.2", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "finalhandler": "1.1.1", "fresh": "0.5.2", "merge-descriptors": "1.0.1", - "methods": "1.1.2", - "on-finished": "2.3.0", - "parseurl": "1.3.2", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", "path-to-regexp": "0.1.7", - "proxy-addr": "2.0.4", + "proxy-addr": "~2.0.4", "qs": "6.5.2", - "range-parser": "1.2.0", + "range-parser": "~1.2.0", "safe-buffer": "5.1.2", "send": "0.16.2", "serve-static": "1.13.2", "setprototypeof": "1.1.0", - "statuses": "1.4.0", - "type-is": "1.6.16", + "statuses": "~1.4.0", + "type-is": "~1.6.16", "utils-merge": "1.0.1", - "vary": "1.1.2" + "vary": "~1.1.2" } }, "extend-shallow": { @@ -653,8 +700,8 @@ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { - "assign-symbols": "1.0.0", - "is-extendable": "1.0.1" + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -663,7 +710,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -674,14 +721,14 @@ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -690,7 +737,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "extend-shallow": { @@ -699,7 +746,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "is-accessor-descriptor": { @@ -708,7 +755,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -717,7 +764,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -726,9 +773,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -739,10 +786,10 @@ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "dependencies": { "extend-shallow": { @@ -751,7 +798,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -762,12 +809,12 @@ "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "requires": { "debug": "2.6.9", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "statuses": "1.4.0", - "unpipe": "1.0.0" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" } }, "for-in": { @@ -787,7 +834,7 @@ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { - "map-cache": "0.2.2" + "map-cache": "^0.2.2" } }, "fresh": { @@ -802,8 +849,8 @@ "dev": true, "optional": true, "requires": { - "nan": "2.11.1", - "node-pre-gyp": "0.10.0" + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" }, "dependencies": { "abbrev": { @@ -836,12 +883,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "1.0.0", "concat-map": "0.0.1" @@ -856,17 +905,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -983,7 +1035,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -995,6 +1048,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "1.0.1" } @@ -1009,6 +1063,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "1.1.11" } @@ -1016,12 +1071,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "5.1.1", "yallist": "3.0.2" @@ -1040,6 +1097,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -1120,7 +1178,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -1132,6 +1191,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1.0.2" } @@ -1253,6 +1313,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "1.1.0", "is-fullwidth-code-point": "1.0.0", @@ -1342,8 +1403,8 @@ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" }, "dependencies": { "is-glob": { @@ -1352,7 +1413,7 @@ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.0" } } } @@ -1363,7 +1424,7 @@ "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", "dev": true, "requires": { - "ini": "1.3.5" + "ini": "^1.3.4" } }, "got": { @@ -1372,17 +1433,17 @@ "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", "dev": true, "requires": { - "create-error-class": "3.0.2", - "duplexer3": "0.1.4", - "get-stream": "3.0.0", - "is-redirect": "1.0.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "lowercase-keys": "1.0.1", - "safe-buffer": "5.1.2", - "timed-out": "4.0.1", - "unzip-response": "2.0.1", - "url-parse-lax": "1.0.0" + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" } }, "graceful-fs": { @@ -1403,9 +1464,9 @@ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "1.0.0", - "isobject": "3.0.1" + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" } }, "has-values": { @@ -1414,8 +1475,8 @@ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "dependencies": { "kind-of": { @@ -1424,7 +1485,7 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1434,10 +1495,10 @@ "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "requires": { - "depd": "1.1.2", + "depd": "~1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.0", - "statuses": "1.4.0" + "statuses": ">= 1.4.0 < 2" } }, "iconv-lite": { @@ -1445,7 +1506,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore-by-default": { @@ -1488,7 +1549,7 @@ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -1497,7 +1558,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1508,7 +1569,7 @@ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "1.12.0" + "binary-extensions": "^1.0.0" } }, "is-buffer": { @@ -1523,7 +1584,7 @@ "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", "dev": true, "requires": { - "ci-info": "1.6.0" + "ci-info": "^1.5.0" } }, "is-data-descriptor": { @@ -1532,7 +1593,7 @@ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -1541,7 +1602,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1552,9 +1613,9 @@ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" }, "dependencies": { "kind-of": { @@ -1589,7 +1650,7 @@ "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.1" } }, "is-installed-globally": { @@ -1598,8 +1659,8 @@ "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", "dev": true, "requires": { - "global-dirs": "0.1.1", - "is-path-inside": "1.0.1" + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" } }, "is-npm": { @@ -1614,7 +1675,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -1623,7 +1684,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1640,7 +1701,7 @@ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "dev": true, "requires": { - "path-is-inside": "1.0.2" + "path-is-inside": "^1.0.1" } }, "is-plain-object": { @@ -1649,7 +1710,7 @@ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" } }, "is-redirect": { @@ -1706,7 +1767,7 @@ "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", "dev": true, "requires": { - "package-json": "4.0.1" + "package-json": "^4.0.0" } }, "lodash.debounce": { @@ -1727,8 +1788,8 @@ "integrity": "sha512-EPstzZ23znHUVLKj+lcXO1KvZkrlw+ZirdwvOmnAnA/1PB4ggyXJ77LRkCqkff+ShQ+cqoxCxLQOh4cKITO5iA==", "dev": true, "requires": { - "pseudomap": "1.0.2", - "yallist": "3.0.3" + "pseudomap": "^1.0.2", + "yallist": "^3.0.2" } }, "make-dir": { @@ -1737,7 +1798,7 @@ "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, "requires": { - "pify": "3.0.0" + "pify": "^3.0.0" } }, "map-cache": { @@ -1752,7 +1813,7 @@ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { - "object-visit": "1.0.1" + "object-visit": "^1.0.0" } }, "media-typer": { @@ -1776,19 +1837,19 @@ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.13", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } }, "mime": { @@ -1806,7 +1867,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", "requires": { - "mime-db": "1.37.0" + "mime-db": "~1.37.0" } }, "minimatch": { @@ -1815,7 +1876,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -1824,27 +1885,6 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, - "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", - "dev": true, - "requires": { - "for-in": "1.0.2", - "is-extendable": "1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "2.0.4" - } - } - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -1863,17 +1903,17 @@ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "fragment-cache": "0.2.1", - "is-windows": "1.0.2", - "kind-of": "6.0.2", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" } }, "negotiator": { @@ -1887,25 +1927,46 @@ "integrity": "sha512-xuC1V0F5EcEyKQ1VhHYD13owznQbUw29JKvZ8bVH7TmuvVNHvvbp9pLgE4PjTMRJVe0pJ8fGRvwR2nMiosIsPQ==", "dev": true, "requires": { - "chokidar": "2.0.4", - "debug": "3.2.6", - "ignore-by-default": "1.0.1", - "minimatch": "3.0.4", - "pstree.remy": "1.1.2", - "semver": "5.6.0", - "supports-color": "5.5.0", - "touch": "3.1.0", - "undefsafe": "2.0.2", - "update-notifier": "2.5.0" + "chokidar": "^2.0.4", + "debug": "^3.1.0", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.2", + "semver": "^5.5.0", + "supports-color": "^5.2.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.2", + "update-notifier": "^2.3.0" }, "dependencies": { + "chokidar": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.0", + "braces": "^2.3.0", + "fsevents": "^1.2.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "lodash.debounce": "^4.0.8", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0", + "upath": "^1.0.5" + } + }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "ms": { @@ -1922,7 +1983,7 @@ "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", "dev": true, "requires": { - "abbrev": "1.1.1" + "abbrev": "1" } }, "normalize-path": { @@ -1931,7 +1992,7 @@ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { - "remove-trailing-separator": "1.1.0" + "remove-trailing-separator": "^1.0.1" } }, "npm-run-path": { @@ -1940,7 +2001,7 @@ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, "requires": { - "path-key": "2.0.1" + "path-key": "^2.0.0" } }, "object-copy": { @@ -1949,9 +2010,9 @@ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { - "copy-descriptor": "0.1.1", - "define-property": "0.2.5", - "kind-of": "3.2.2" + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" }, "dependencies": { "define-property": { @@ -1960,7 +2021,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "kind-of": { @@ -1969,7 +2030,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1980,7 +2041,7 @@ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.0" } }, "object.pick": { @@ -1989,7 +2050,7 @@ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" } }, "on-finished": { @@ -2012,10 +2073,10 @@ "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", "dev": true, "requires": { - "got": "6.7.1", - "registry-auth-token": "3.3.2", - "registry-url": "3.1.0", - "semver": "5.6.0" + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" } }, "parseurl": { @@ -2087,7 +2148,7 @@ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", "requires": { - "forwarded": "0.1.2", + "forwarded": "~0.1.2", "ipaddr.js": "1.8.0" } }, @@ -2130,10 +2191,10 @@ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, "requires": { - "deep-extend": "0.6.0", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" } }, "readable-stream": { @@ -2142,13 +2203,13 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "readdirp": { @@ -2157,9 +2218,9 @@ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "micromatch": "3.1.10", - "readable-stream": "2.3.6" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" } }, "regex-not": { @@ -2168,8 +2229,8 @@ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "requires": { - "extend-shallow": "3.0.2", - "safe-regex": "1.1.0" + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" } }, "registry-auth-token": { @@ -2178,8 +2239,8 @@ "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", "dev": true, "requires": { - "rc": "1.2.8", - "safe-buffer": "5.1.2" + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" } }, "registry-url": { @@ -2188,7 +2249,7 @@ "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", "dev": true, "requires": { - "rc": "1.2.8" + "rc": "^1.0.1" } }, "remove-trailing-separator": { @@ -2232,7 +2293,7 @@ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { - "ret": "0.1.15" + "ret": "~0.1.10" } }, "safer-buffer": { @@ -2252,7 +2313,7 @@ "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", "dev": true, "requires": { - "semver": "5.6.0" + "semver": "^5.0.3" } }, "send": { @@ -2261,18 +2322,18 @@ "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", "requires": { "debug": "2.6.9", - "depd": "1.1.2", - "destroy": "1.0.4", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.6.3", + "http-errors": "~1.6.2", "mime": "1.4.1", "ms": "2.0.0", - "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.4.0" + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" } }, "serve-static": { @@ -2280,35 +2341,12 @@ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", "requires": { - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "parseurl": "1.3.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", "send": "0.16.2" } }, - "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "dev": true, - "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "split-string": "3.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } - } - }, "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", @@ -2320,7 +2358,7 @@ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { - "shebang-regex": "1.0.0" + "shebang-regex": "^1.0.0" } }, "shebang-regex": { @@ -2341,14 +2379,14 @@ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { - "base": "0.11.2", - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "map-cache": "0.2.2", - "source-map": "0.5.7", - "source-map-resolve": "0.5.2", - "use": "3.1.1" + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" }, "dependencies": { "define-property": { @@ -2357,7 +2395,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -2366,7 +2404,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -2377,9 +2415,9 @@ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "requires": { - "define-property": "1.0.0", - "isobject": "3.0.1", - "snapdragon-util": "3.0.1" + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" }, "dependencies": { "define-property": { @@ -2388,7 +2426,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -2397,7 +2435,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -2406,7 +2444,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -2415,9 +2453,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -2428,7 +2466,7 @@ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.2.0" }, "dependencies": { "kind-of": { @@ -2437,7 +2475,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -2454,11 +2492,11 @@ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "dev": true, "requires": { - "atob": "2.1.2", - "decode-uri-component": "0.2.0", - "resolve-url": "0.2.1", - "source-map-url": "0.4.0", - "urix": "0.1.0" + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" } }, "source-map-url": { @@ -2473,7 +2511,7 @@ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "requires": { - "extend-shallow": "3.0.2" + "extend-shallow": "^3.0.0" } }, "static-extend": { @@ -2482,8 +2520,8 @@ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { - "define-property": "0.2.5", - "object-copy": "0.1.0" + "define-property": "^0.2.5", + "object-copy": "^0.1.0" }, "dependencies": { "define-property": { @@ -2492,7 +2530,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -2508,8 +2546,8 @@ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" } }, "string_decoder": { @@ -2518,7 +2556,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { @@ -2527,7 +2565,7 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } }, "strip-eof": { @@ -2548,7 +2586,7 @@ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } }, "term-size": { @@ -2557,7 +2595,7 @@ "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", "dev": true, "requires": { - "execa": "0.7.0" + "execa": "^0.7.0" } }, "timed-out": { @@ -2572,7 +2610,7 @@ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -2581,7 +2619,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -2592,10 +2630,10 @@ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "regex-not": "1.0.2", - "safe-regex": "1.1.0" + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" } }, "to-regex-range": { @@ -2604,8 +2642,8 @@ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { - "is-number": "3.0.0", - "repeat-string": "1.6.1" + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" } }, "touch": { @@ -2614,7 +2652,7 @@ "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", "dev": true, "requires": { - "nopt": "1.0.10" + "nopt": "~1.0.10" } }, "type-is": { @@ -2623,7 +2661,7 @@ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", "requires": { "media-typer": "0.3.0", - "mime-types": "2.1.21" + "mime-types": "~2.1.18" } }, "undefsafe": { @@ -2632,42 +2670,7 @@ "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", "dev": true, "requires": { - "debug": "2.6.9" - } - }, - "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "dev": true, - "requires": { - "arr-union": "3.1.0", - "get-value": "2.0.6", - "is-extendable": "0.1.1", - "set-value": "0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "to-object-path": "0.3.0" - } - } + "debug": "^2.2.0" } }, "unique-string": { @@ -2676,7 +2679,7 @@ "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", "dev": true, "requires": { - "crypto-random-string": "1.0.0" + "crypto-random-string": "^1.0.0" } }, "unpipe": { @@ -2690,8 +2693,8 @@ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { - "has-value": "0.3.1", - "isobject": "3.0.1" + "has-value": "^0.3.1", + "isobject": "^3.0.0" }, "dependencies": { "has-value": { @@ -2700,9 +2703,9 @@ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "0.1.4", - "isobject": "2.1.0" + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" }, "dependencies": { "isobject": { @@ -2742,16 +2745,16 @@ "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", "dev": true, "requires": { - "boxen": "1.3.0", - "chalk": "2.4.1", - "configstore": "3.1.2", - "import-lazy": "2.1.0", - "is-ci": "1.2.1", - "is-installed-globally": "0.1.0", - "is-npm": "1.0.0", - "latest-version": "3.1.0", - "semver-diff": "2.1.0", - "xdg-basedir": "3.0.0" + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" } }, "urix": { @@ -2766,7 +2769,7 @@ "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", "dev": true, "requires": { - "prepend-http": "1.0.4" + "prepend-http": "^1.0.1" } }, "use": { @@ -2797,7 +2800,7 @@ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { - "isexe": "2.0.0" + "isexe": "^2.0.0" } }, "widest-line": { @@ -2806,7 +2809,7 @@ "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", "dev": true, "requires": { - "string-width": "2.1.1" + "string-width": "^2.1.1" } }, "write-file-atomic": { @@ -2815,9 +2818,9 @@ "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "imurmurhash": "0.1.4", - "signal-exit": "3.0.2" + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" } }, "xdg-basedir": { diff --git a/integration/examples/nodejs/backend/package.json b/integration/examples/nodejs/backend/package.json index 66ddb0badf3..843517e9b4f 100644 --- a/integration/examples/nodejs/backend/package.json +++ b/integration/examples/nodejs/backend/package.json @@ -12,4 +12,4 @@ "devDependencies": { "nodemon": "^1.18.4" } -} \ No newline at end of file +} From 8340f708c857005f2ddfde4972b6aed1e37dd01e Mon Sep 17 00:00:00 2001 From: balopat Date: Thu, 29 Aug 2019 13:58:38 -0700 Subject: [PATCH 66/69] more npm audit fix --- .../examples/nodejs/backend/package-lock.json | 475 +++++++++--------- 1 file changed, 225 insertions(+), 250 deletions(-) diff --git a/integration/examples/nodejs/backend/package-lock.json b/integration/examples/nodejs/backend/package-lock.json index 32f0279a77b..b45984085aa 100644 --- a/integration/examples/nodejs/backend/package-lock.json +++ b/integration/examples/nodejs/backend/package-lock.json @@ -51,6 +51,17 @@ "requires": { "micromatch": "^3.1.4", "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } } }, "arr-diff": { @@ -89,9 +100,9 @@ "dev": true }, "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", "dev": true }, "atob": { @@ -158,32 +169,13 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - } } } }, "binary-extensions": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", - "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, "body-parser": { @@ -277,55 +269,6 @@ "to-object-path": "^0.3.0", "union-value": "^1.0.0", "unset-value": "^1.0.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - } - }, - "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } - } - } } }, "camelcase": { @@ -351,6 +294,26 @@ "supports-color": "^5.3.0" } }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, "ci-info": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", @@ -412,9 +375,9 @@ "dev": true }, "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, "concat-map": { @@ -843,14 +806,14 @@ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", "dev": true, "optional": true, "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" }, "dependencies": { "abbrev": { @@ -871,33 +834,31 @@ "optional": true }, "are-we-there-yet": { - "version": "1.1.4", + "version": "1.1.5", "bundled": true, "dev": true, "optional": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.6" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "chownr": { - "version": "1.0.1", + "version": "1.1.1", "bundled": true, "dev": true, "optional": true @@ -905,20 +866,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -927,16 +885,16 @@ "optional": true }, "debug": { - "version": "2.6.9", + "version": "4.1.1", "bundled": true, "dev": true, "optional": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "deep-extend": { - "version": "0.5.1", + "version": "0.6.0", "bundled": true, "dev": true, "optional": true @@ -959,7 +917,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "fs.realpath": { @@ -974,28 +932,28 @@ "dev": true, "optional": true, "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } }, "glob": { - "version": "7.1.2", + "version": "7.1.3", "bundled": true, "dev": true, "optional": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "has-unicode": { @@ -1005,12 +963,12 @@ "optional": true }, "iconv-lite": { - "version": "0.4.21", + "version": "0.4.24", "bundled": true, "dev": true, "optional": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore-walk": { @@ -1019,7 +977,7 @@ "dev": true, "optional": true, "requires": { - "minimatch": "3.0.4" + "minimatch": "^3.0.4" } }, "inflight": { @@ -1028,15 +986,14 @@ "dev": true, "optional": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -1048,9 +1005,8 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "isarray": { @@ -1063,78 +1019,74 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { - "version": "2.2.4", + "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" } }, "minizlib": { - "version": "1.1.0", + "version": "1.2.1", "bundled": true, "dev": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "mkdirp": { "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } }, "ms": { - "version": "2.0.0", + "version": "2.1.1", "bundled": true, "dev": true, "optional": true }, "needle": { - "version": "2.2.0", + "version": "2.3.0", "bundled": true, "dev": true, "optional": true, "requires": { - "debug": "2.6.9", - "iconv-lite": "0.4.21", - "sax": "1.2.4" + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" } }, "node-pre-gyp": { - "version": "0.10.0", + "version": "0.12.0", "bundled": true, "dev": true, "optional": true, "requires": { - "detect-libc": "1.0.3", - "mkdirp": "0.5.1", - "needle": "2.2.0", - "nopt": "4.0.1", - "npm-packlist": "1.1.10", - "npmlog": "4.1.2", - "rc": "1.2.7", - "rimraf": "2.6.2", - "semver": "5.5.0", - "tar": "4.4.1" + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" } }, "nopt": { @@ -1143,24 +1095,24 @@ "dev": true, "optional": true, "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.5" + "abbrev": "1", + "osenv": "^0.1.4" } }, "npm-bundled": { - "version": "1.0.3", + "version": "1.0.6", "bundled": true, "dev": true, "optional": true }, "npm-packlist": { - "version": "1.1.10", + "version": "1.4.1", "bundled": true, "dev": true, "optional": true, "requires": { - "ignore-walk": "3.0.1", - "npm-bundled": "1.0.3" + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" } }, "npmlog": { @@ -1169,17 +1121,16 @@ "dev": true, "optional": true, "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -1191,9 +1142,8 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "os-homedir": { @@ -1214,8 +1164,8 @@ "dev": true, "optional": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "path-is-absolute": { @@ -1231,15 +1181,15 @@ "optional": true }, "rc": { - "version": "1.2.7", + "version": "1.2.8", "bundled": true, "dev": true, "optional": true, "requires": { - "deep-extend": "0.5.1", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { "minimist": { @@ -1256,26 +1206,26 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "rimraf": { - "version": "2.6.2", + "version": "2.6.3", "bundled": true, "dev": true, "optional": true, "requires": { - "glob": "7.1.2" + "glob": "^7.1.3" } }, "safe-buffer": { - "version": "5.1.1", + "version": "5.1.2", "bundled": true, "dev": true }, @@ -1292,7 +1242,7 @@ "optional": true }, "semver": { - "version": "5.5.0", + "version": "5.7.0", "bundled": true, "dev": true, "optional": true @@ -1313,11 +1263,10 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { @@ -1326,7 +1275,7 @@ "dev": true, "optional": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { @@ -1334,7 +1283,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-json-comments": { @@ -1344,18 +1293,18 @@ "optional": true }, "tar": { - "version": "4.4.1", + "version": "4.4.8", "bundled": true, "dev": true, "optional": true, "requires": { - "chownr": "1.0.1", - "fs-minipass": "1.2.5", - "minipass": "2.2.4", - "minizlib": "1.1.0", - "mkdirp": "0.5.1", - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" } }, "util-deprecate": { @@ -1365,12 +1314,12 @@ "optional": true }, "wide-align": { - "version": "1.1.2", + "version": "1.1.3", "bundled": true, "dev": true, "optional": true, "requires": { - "string-width": "1.0.2" + "string-width": "^1.0.2 || 2" } }, "wrappy": { @@ -1379,7 +1328,7 @@ "dev": true }, "yallist": { - "version": "3.0.2", + "version": "3.0.3", "bundled": true, "dev": true } @@ -1645,9 +1594,9 @@ "dev": true }, "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { "is-extglob": "^2.1.1" @@ -1770,12 +1719,6 @@ "package-json": "^4.0.0" } }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -1885,15 +1828,36 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "nan": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", - "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", "dev": true, "optional": true }, @@ -1939,27 +1903,6 @@ "update-notifier": "^2.3.0" }, "dependencies": { - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" - } - }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -1987,13 +1930,10 @@ } }, "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "npm-run-path": { "version": "2.0.2", @@ -2098,7 +2038,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, @@ -2138,9 +2078,9 @@ "dev": true }, "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, "proxy-addr": { @@ -2199,7 +2139,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { @@ -2289,7 +2229,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { @@ -2347,6 +2287,29 @@ "send": "0.16.2" } }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", @@ -2552,7 +2515,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { @@ -2673,6 +2636,18 @@ "debug": "^2.2.0" } }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, "unique-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", @@ -2734,9 +2709,9 @@ "dev": true }, "upath": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", "dev": true }, "update-notifier": { From 1bd557eb27a54c8bd3dc57fd4a39a30fdd5b8743 Mon Sep 17 00:00:00 2001 From: balopat Date: Thu, 29 Aug 2019 13:59:46 -0700 Subject: [PATCH 67/69] more npm audit fix --- examples/nodejs/backend/package-lock.json | 467 +++++++++--------- .../examples/nodejs/backend/package-lock.json | 8 +- 2 files changed, 225 insertions(+), 250 deletions(-) diff --git a/examples/nodejs/backend/package-lock.json b/examples/nodejs/backend/package-lock.json index 32f0279a77b..2fdf304744f 100644 --- a/examples/nodejs/backend/package-lock.json +++ b/examples/nodejs/backend/package-lock.json @@ -51,6 +51,17 @@ "requires": { "micromatch": "^3.1.4", "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } } }, "arr-diff": { @@ -89,9 +100,9 @@ "dev": true }, "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", "dev": true }, "atob": { @@ -158,32 +169,13 @@ "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - } } } }, "binary-extensions": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", - "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, "body-parser": { @@ -277,55 +269,6 @@ "to-object-path": "^0.3.0", "union-value": "^1.0.0", "unset-value": "^1.0.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - } - }, - "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } - } - } } }, "camelcase": { @@ -351,6 +294,26 @@ "supports-color": "^5.3.0" } }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, "ci-info": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", @@ -412,9 +375,9 @@ "dev": true }, "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, "concat-map": { @@ -843,14 +806,14 @@ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", "dev": true, "optional": true, "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" }, "dependencies": { "abbrev": { @@ -871,33 +834,31 @@ "optional": true }, "are-we-there-yet": { - "version": "1.1.4", + "version": "1.1.5", "bundled": true, "dev": true, "optional": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.6" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "chownr": { - "version": "1.0.1", + "version": "1.1.1", "bundled": true, "dev": true, "optional": true @@ -905,20 +866,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -927,16 +885,16 @@ "optional": true }, "debug": { - "version": "2.6.9", + "version": "4.1.1", "bundled": true, "dev": true, "optional": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "deep-extend": { - "version": "0.5.1", + "version": "0.6.0", "bundled": true, "dev": true, "optional": true @@ -959,7 +917,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "fs.realpath": { @@ -974,28 +932,28 @@ "dev": true, "optional": true, "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } }, "glob": { - "version": "7.1.2", + "version": "7.1.3", "bundled": true, "dev": true, "optional": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "has-unicode": { @@ -1005,12 +963,12 @@ "optional": true }, "iconv-lite": { - "version": "0.4.21", + "version": "0.4.24", "bundled": true, "dev": true, "optional": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore-walk": { @@ -1019,7 +977,7 @@ "dev": true, "optional": true, "requires": { - "minimatch": "3.0.4" + "minimatch": "^3.0.4" } }, "inflight": { @@ -1028,15 +986,14 @@ "dev": true, "optional": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -1048,9 +1005,8 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "isarray": { @@ -1063,78 +1019,74 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { - "version": "2.2.4", + "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" } }, "minizlib": { - "version": "1.1.0", + "version": "1.2.1", "bundled": true, "dev": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "mkdirp": { "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } }, "ms": { - "version": "2.0.0", + "version": "2.1.1", "bundled": true, "dev": true, "optional": true }, "needle": { - "version": "2.2.0", + "version": "2.3.0", "bundled": true, "dev": true, "optional": true, "requires": { - "debug": "2.6.9", - "iconv-lite": "0.4.21", - "sax": "1.2.4" + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" } }, "node-pre-gyp": { - "version": "0.10.0", + "version": "0.12.0", "bundled": true, "dev": true, "optional": true, "requires": { - "detect-libc": "1.0.3", - "mkdirp": "0.5.1", - "needle": "2.2.0", - "nopt": "4.0.1", - "npm-packlist": "1.1.10", - "npmlog": "4.1.2", - "rc": "1.2.7", - "rimraf": "2.6.2", - "semver": "5.5.0", - "tar": "4.4.1" + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" } }, "nopt": { @@ -1143,24 +1095,24 @@ "dev": true, "optional": true, "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.5" + "abbrev": "1", + "osenv": "^0.1.4" } }, "npm-bundled": { - "version": "1.0.3", + "version": "1.0.6", "bundled": true, "dev": true, "optional": true }, "npm-packlist": { - "version": "1.1.10", + "version": "1.4.1", "bundled": true, "dev": true, "optional": true, "requires": { - "ignore-walk": "3.0.1", - "npm-bundled": "1.0.3" + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" } }, "npmlog": { @@ -1169,17 +1121,16 @@ "dev": true, "optional": true, "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -1191,9 +1142,8 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "os-homedir": { @@ -1214,8 +1164,8 @@ "dev": true, "optional": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "path-is-absolute": { @@ -1231,15 +1181,15 @@ "optional": true }, "rc": { - "version": "1.2.7", + "version": "1.2.8", "bundled": true, "dev": true, "optional": true, "requires": { - "deep-extend": "0.5.1", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { "minimist": { @@ -1256,26 +1206,26 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "rimraf": { - "version": "2.6.2", + "version": "2.6.3", "bundled": true, "dev": true, "optional": true, "requires": { - "glob": "7.1.2" + "glob": "^7.1.3" } }, "safe-buffer": { - "version": "5.1.1", + "version": "5.1.2", "bundled": true, "dev": true }, @@ -1292,7 +1242,7 @@ "optional": true }, "semver": { - "version": "5.5.0", + "version": "5.7.0", "bundled": true, "dev": true, "optional": true @@ -1313,11 +1263,10 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { @@ -1326,7 +1275,7 @@ "dev": true, "optional": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { @@ -1334,7 +1283,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-json-comments": { @@ -1344,18 +1293,18 @@ "optional": true }, "tar": { - "version": "4.4.1", + "version": "4.4.8", "bundled": true, "dev": true, "optional": true, "requires": { - "chownr": "1.0.1", - "fs-minipass": "1.2.5", - "minipass": "2.2.4", - "minizlib": "1.1.0", - "mkdirp": "0.5.1", - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" } }, "util-deprecate": { @@ -1365,12 +1314,12 @@ "optional": true }, "wide-align": { - "version": "1.1.2", + "version": "1.1.3", "bundled": true, "dev": true, "optional": true, "requires": { - "string-width": "1.0.2" + "string-width": "^1.0.2 || 2" } }, "wrappy": { @@ -1379,7 +1328,7 @@ "dev": true }, "yallist": { - "version": "3.0.2", + "version": "3.0.3", "bundled": true, "dev": true } @@ -1645,9 +1594,9 @@ "dev": true }, "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { "is-extglob": "^2.1.1" @@ -1770,12 +1719,6 @@ "package-json": "^4.0.0" } }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -1885,15 +1828,36 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "nan": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", - "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", "dev": true, "optional": true }, @@ -1939,27 +1903,6 @@ "update-notifier": "^2.3.0" }, "dependencies": { - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" - } - }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -1987,13 +1930,10 @@ } }, "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "npm-run-path": { "version": "2.0.2", @@ -2138,9 +2078,9 @@ "dev": true }, "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, "proxy-addr": { @@ -2347,6 +2287,29 @@ "send": "0.16.2" } }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", @@ -2673,6 +2636,18 @@ "debug": "^2.2.0" } }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, "unique-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", @@ -2734,9 +2709,9 @@ "dev": true }, "upath": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", "dev": true }, "update-notifier": { diff --git a/integration/examples/nodejs/backend/package-lock.json b/integration/examples/nodejs/backend/package-lock.json index b45984085aa..2fdf304744f 100644 --- a/integration/examples/nodejs/backend/package-lock.json +++ b/integration/examples/nodejs/backend/package-lock.json @@ -2038,7 +2038,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, @@ -2139,7 +2139,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { @@ -2229,7 +2229,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { @@ -2515,7 +2515,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { From 4ab465f044c61152f319b6f918aa9c1f2acdbf53 Mon Sep 17 00:00:00 2001 From: balopat Date: Thu, 29 Aug 2019 17:11:58 -0700 Subject: [PATCH 68/69] more npm audit fix --- examples/hot-reload/node/package-lock.json | 1046 ++++++++--------- examples/hot-reload/node/package.json | 2 +- .../hot-reload/node/package-lock.json | 1046 ++++++++--------- .../examples/hot-reload/node/package.json | 2 +- 4 files changed, 1026 insertions(+), 1070 deletions(-) diff --git a/examples/hot-reload/node/package-lock.json b/examples/hot-reload/node/package-lock.json index a3ae06edb4d..2fdf304744f 100644 --- a/examples/hot-reload/node/package-lock.json +++ b/examples/hot-reload/node/package-lock.json @@ -15,7 +15,7 @@ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "requires": { - "mime-types": "2.1.21", + "mime-types": "~2.1.18", "negotiator": "0.6.1" } }, @@ -25,7 +25,7 @@ "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", "dev": true, "requires": { - "string-width": "2.1.1" + "string-width": "^2.0.0" } }, "ansi-regex": { @@ -40,7 +40,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.3" + "color-convert": "^1.9.0" } }, "anymatch": { @@ -49,8 +49,19 @@ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "micromatch": "3.1.10", - "normalize-path": "2.1.1" + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } } }, "arr-diff": { @@ -89,9 +100,9 @@ "dev": true }, "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", "dev": true }, "atob": { @@ -112,13 +123,13 @@ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { - "cache-base": "1.0.1", - "class-utils": "0.3.6", - "component-emitter": "1.2.1", - "define-property": "1.0.0", - "isobject": "3.0.1", - "mixin-deep": "1.3.1", - "pascalcase": "0.1.1" + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" }, "dependencies": { "define-property": { @@ -127,7 +138,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -136,7 +147,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -145,7 +156,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -154,17 +165,17 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } }, "binary-extensions": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", - "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, "body-parser": { @@ -173,15 +184,15 @@ "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", "requires": { "bytes": "3.0.0", - "content-type": "1.0.4", + "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "1.1.2", - "http-errors": "1.6.3", + "depd": "~1.1.2", + "http-errors": "~1.6.3", "iconv-lite": "0.4.23", - "on-finished": "2.3.0", + "on-finished": "~2.3.0", "qs": "6.5.2", "raw-body": "2.3.3", - "type-is": "1.6.16" + "type-is": "~1.6.16" } }, "boxen": { @@ -190,13 +201,13 @@ "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", "dev": true, "requires": { - "ansi-align": "2.0.0", - "camelcase": "4.1.0", - "chalk": "2.4.1", - "cli-boxes": "1.0.0", - "string-width": "2.1.1", - "term-size": "1.2.0", - "widest-line": "2.0.1" + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" } }, "brace-expansion": { @@ -205,7 +216,7 @@ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -215,16 +226,16 @@ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "repeat-element": "1.1.3", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -233,7 +244,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -249,15 +260,15 @@ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { - "collection-visit": "1.0.0", - "component-emitter": "1.2.1", - "get-value": "2.0.6", - "has-value": "1.0.0", - "isobject": "3.0.1", - "set-value": "2.0.0", - "to-object-path": "0.3.0", - "union-value": "1.0.0", - "unset-value": "1.0.0" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" } }, "camelcase": { @@ -278,30 +289,29 @@ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.5.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", "dev": true, "requires": { - "anymatch": "2.0.0", - "async-each": "1.0.1", - "braces": "2.3.2", - "fsevents": "1.2.4", - "glob-parent": "3.1.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "4.0.0", - "lodash.debounce": "4.0.8", - "normalize-path": "2.1.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.2.1", - "upath": "1.1.0" + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" } }, "ci-info": { @@ -316,10 +326,10 @@ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { - "arr-union": "3.1.0", - "define-property": "0.2.5", - "isobject": "3.0.1", - "static-extend": "0.1.2" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, "dependencies": { "define-property": { @@ -328,7 +338,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -345,8 +355,8 @@ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { - "map-visit": "1.0.0", - "object-visit": "1.0.1" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, "color-convert": { @@ -365,9 +375,9 @@ "dev": true }, "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, "concat-map": { @@ -382,12 +392,12 @@ "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", "dev": true, "requires": { - "dot-prop": "4.2.0", - "graceful-fs": "4.1.15", - "make-dir": "1.3.0", - "unique-string": "1.0.0", - "write-file-atomic": "2.3.0", - "xdg-basedir": "3.0.0" + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" } }, "content-disposition": { @@ -428,7 +438,7 @@ "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", "dev": true, "requires": { - "capture-stack-trace": "1.0.1" + "capture-stack-trace": "^1.0.0" } }, "cross-spawn": { @@ -437,9 +447,9 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "4.1.4", - "shebang-command": "1.2.0", - "which": "1.3.1" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "crypto-random-string": { @@ -474,8 +484,8 @@ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { - "is-descriptor": "1.0.2", - "isobject": "3.0.1" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "dependencies": { "is-accessor-descriptor": { @@ -484,7 +494,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -493,7 +503,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -502,9 +512,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -525,7 +535,7 @@ "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", "dev": true, "requires": { - "is-obj": "1.0.1" + "is-obj": "^1.0.0" } }, "duplexer3": { @@ -566,13 +576,13 @@ "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "dev": true, "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" } }, "expand-brackets": { @@ -581,13 +591,13 @@ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -596,7 +606,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -605,7 +615,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -615,36 +625,36 @@ "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", "requires": { - "accepts": "1.3.5", + "accepts": "~1.3.5", "array-flatten": "1.1.1", "body-parser": "1.18.3", "content-disposition": "0.5.2", - "content-type": "1.0.4", + "content-type": "~1.0.4", "cookie": "0.3.1", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "1.1.2", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "finalhandler": "1.1.1", "fresh": "0.5.2", "merge-descriptors": "1.0.1", - "methods": "1.1.2", - "on-finished": "2.3.0", - "parseurl": "1.3.2", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", "path-to-regexp": "0.1.7", - "proxy-addr": "2.0.4", + "proxy-addr": "~2.0.4", "qs": "6.5.2", - "range-parser": "1.2.0", + "range-parser": "~1.2.0", "safe-buffer": "5.1.2", "send": "0.16.2", "serve-static": "1.13.2", "setprototypeof": "1.1.0", - "statuses": "1.4.0", - "type-is": "1.6.16", + "statuses": "~1.4.0", + "type-is": "~1.6.16", "utils-merge": "1.0.1", - "vary": "1.1.2" + "vary": "~1.1.2" } }, "extend-shallow": { @@ -653,8 +663,8 @@ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { - "assign-symbols": "1.0.0", - "is-extendable": "1.0.1" + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -663,7 +673,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -674,14 +684,14 @@ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -690,7 +700,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "extend-shallow": { @@ -699,7 +709,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "is-accessor-descriptor": { @@ -708,7 +718,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -717,7 +727,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -726,9 +736,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -739,10 +749,10 @@ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "dependencies": { "extend-shallow": { @@ -751,7 +761,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -762,12 +772,12 @@ "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "requires": { "debug": "2.6.9", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "statuses": "1.4.0", - "unpipe": "1.0.0" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" } }, "for-in": { @@ -787,7 +797,7 @@ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { - "map-cache": "0.2.2" + "map-cache": "^0.2.2" } }, "fresh": { @@ -796,14 +806,14 @@ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", "dev": true, "optional": true, "requires": { - "nan": "2.11.1", - "node-pre-gyp": "0.10.0" + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" }, "dependencies": { "abbrev": { @@ -824,13 +834,13 @@ "optional": true }, "are-we-there-yet": { - "version": "1.1.4", + "version": "1.1.5", "bundled": true, "dev": true, "optional": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.6" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, "balanced-match": { @@ -843,12 +853,12 @@ "bundled": true, "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "chownr": { - "version": "1.0.1", + "version": "1.1.1", "bundled": true, "dev": true, "optional": true @@ -875,16 +885,16 @@ "optional": true }, "debug": { - "version": "2.6.9", + "version": "4.1.1", "bundled": true, "dev": true, "optional": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "deep-extend": { - "version": "0.5.1", + "version": "0.6.0", "bundled": true, "dev": true, "optional": true @@ -907,7 +917,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "fs.realpath": { @@ -922,28 +932,28 @@ "dev": true, "optional": true, "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } }, "glob": { - "version": "7.1.2", + "version": "7.1.3", "bundled": true, "dev": true, "optional": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "has-unicode": { @@ -953,12 +963,12 @@ "optional": true }, "iconv-lite": { - "version": "0.4.21", + "version": "0.4.24", "bundled": true, "dev": true, "optional": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore-walk": { @@ -967,7 +977,7 @@ "dev": true, "optional": true, "requires": { - "minimatch": "3.0.4" + "minimatch": "^3.0.4" } }, "inflight": { @@ -976,8 +986,8 @@ "dev": true, "optional": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -996,7 +1006,7 @@ "bundled": true, "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "isarray": { @@ -1010,7 +1020,7 @@ "bundled": true, "dev": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -1019,21 +1029,21 @@ "dev": true }, "minipass": { - "version": "2.2.4", + "version": "2.3.5", "bundled": true, "dev": true, "requires": { - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" } }, "minizlib": { - "version": "1.1.0", + "version": "1.2.1", "bundled": true, "dev": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "mkdirp": { @@ -1045,38 +1055,38 @@ } }, "ms": { - "version": "2.0.0", + "version": "2.1.1", "bundled": true, "dev": true, "optional": true }, "needle": { - "version": "2.2.0", + "version": "2.3.0", "bundled": true, "dev": true, "optional": true, "requires": { - "debug": "2.6.9", - "iconv-lite": "0.4.21", - "sax": "1.2.4" + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" } }, "node-pre-gyp": { - "version": "0.10.0", + "version": "0.12.0", "bundled": true, "dev": true, "optional": true, "requires": { - "detect-libc": "1.0.3", - "mkdirp": "0.5.1", - "needle": "2.2.0", - "nopt": "4.0.1", - "npm-packlist": "1.1.10", - "npmlog": "4.1.2", - "rc": "1.2.7", - "rimraf": "2.6.2", - "semver": "5.5.0", - "tar": "4.4.1" + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" } }, "nopt": { @@ -1085,24 +1095,24 @@ "dev": true, "optional": true, "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.5" + "abbrev": "1", + "osenv": "^0.1.4" } }, "npm-bundled": { - "version": "1.0.3", + "version": "1.0.6", "bundled": true, "dev": true, "optional": true }, "npm-packlist": { - "version": "1.1.10", + "version": "1.4.1", "bundled": true, "dev": true, "optional": true, "requires": { - "ignore-walk": "3.0.1", - "npm-bundled": "1.0.3" + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" } }, "npmlog": { @@ -1111,10 +1121,10 @@ "dev": true, "optional": true, "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "number-is-nan": { @@ -1133,7 +1143,7 @@ "bundled": true, "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "os-homedir": { @@ -1154,8 +1164,8 @@ "dev": true, "optional": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "path-is-absolute": { @@ -1171,15 +1181,15 @@ "optional": true }, "rc": { - "version": "1.2.7", + "version": "1.2.8", "bundled": true, "dev": true, "optional": true, "requires": { - "deep-extend": "0.5.1", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { "minimist": { @@ -1196,26 +1206,26 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "rimraf": { - "version": "2.6.2", + "version": "2.6.3", "bundled": true, "dev": true, "optional": true, "requires": { - "glob": "7.1.2" + "glob": "^7.1.3" } }, "safe-buffer": { - "version": "5.1.1", + "version": "5.1.2", "bundled": true, "dev": true }, @@ -1232,7 +1242,7 @@ "optional": true }, "semver": { - "version": "5.5.0", + "version": "5.7.0", "bundled": true, "dev": true, "optional": true @@ -1254,9 +1264,9 @@ "bundled": true, "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { @@ -1265,7 +1275,7 @@ "dev": true, "optional": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { @@ -1273,7 +1283,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-json-comments": { @@ -1283,18 +1293,18 @@ "optional": true }, "tar": { - "version": "4.4.1", + "version": "4.4.8", "bundled": true, "dev": true, "optional": true, "requires": { - "chownr": "1.0.1", - "fs-minipass": "1.2.5", - "minipass": "2.2.4", - "minizlib": "1.1.0", - "mkdirp": "0.5.1", - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" } }, "util-deprecate": { @@ -1304,12 +1314,12 @@ "optional": true }, "wide-align": { - "version": "1.1.2", + "version": "1.1.3", "bundled": true, "dev": true, "optional": true, "requires": { - "string-width": "1.0.2" + "string-width": "^1.0.2 || 2" } }, "wrappy": { @@ -1318,7 +1328,7 @@ "dev": true }, "yallist": { - "version": "3.0.2", + "version": "3.0.3", "bundled": true, "dev": true } @@ -1342,8 +1352,8 @@ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" }, "dependencies": { "is-glob": { @@ -1352,7 +1362,7 @@ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.0" } } } @@ -1363,7 +1373,7 @@ "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", "dev": true, "requires": { - "ini": "1.3.5" + "ini": "^1.3.4" } }, "got": { @@ -1372,17 +1382,17 @@ "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", "dev": true, "requires": { - "create-error-class": "3.0.2", - "duplexer3": "0.1.4", - "get-stream": "3.0.0", - "is-redirect": "1.0.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "lowercase-keys": "1.0.1", - "safe-buffer": "5.1.2", - "timed-out": "4.0.1", - "unzip-response": "2.0.1", - "url-parse-lax": "1.0.0" + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" } }, "graceful-fs": { @@ -1403,9 +1413,9 @@ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "1.0.0", - "isobject": "3.0.1" + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" } }, "has-values": { @@ -1414,8 +1424,8 @@ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "dependencies": { "kind-of": { @@ -1424,7 +1434,7 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1434,10 +1444,10 @@ "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "requires": { - "depd": "1.1.2", + "depd": "~1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.0", - "statuses": "1.4.0" + "statuses": ">= 1.4.0 < 2" } }, "iconv-lite": { @@ -1445,7 +1455,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore-by-default": { @@ -1488,7 +1498,7 @@ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -1497,7 +1507,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1508,7 +1518,7 @@ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "1.12.0" + "binary-extensions": "^1.0.0" } }, "is-buffer": { @@ -1523,7 +1533,7 @@ "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", "dev": true, "requires": { - "ci-info": "1.6.0" + "ci-info": "^1.5.0" } }, "is-data-descriptor": { @@ -1532,7 +1542,7 @@ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -1541,7 +1551,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1552,9 +1562,9 @@ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" }, "dependencies": { "kind-of": { @@ -1584,12 +1594,12 @@ "dev": true }, "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.1" } }, "is-installed-globally": { @@ -1598,8 +1608,8 @@ "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", "dev": true, "requires": { - "global-dirs": "0.1.1", - "is-path-inside": "1.0.1" + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" } }, "is-npm": { @@ -1614,7 +1624,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -1623,7 +1633,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1640,7 +1650,7 @@ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "dev": true, "requires": { - "path-is-inside": "1.0.2" + "path-is-inside": "^1.0.1" } }, "is-plain-object": { @@ -1649,7 +1659,7 @@ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" } }, "is-redirect": { @@ -1706,15 +1716,9 @@ "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", "dev": true, "requires": { - "package-json": "4.0.1" + "package-json": "^4.0.0" } }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -1727,8 +1731,8 @@ "integrity": "sha512-EPstzZ23znHUVLKj+lcXO1KvZkrlw+ZirdwvOmnAnA/1PB4ggyXJ77LRkCqkff+ShQ+cqoxCxLQOh4cKITO5iA==", "dev": true, "requires": { - "pseudomap": "1.0.2", - "yallist": "3.0.3" + "pseudomap": "^1.0.2", + "yallist": "^3.0.2" } }, "make-dir": { @@ -1737,7 +1741,7 @@ "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, "requires": { - "pify": "3.0.0" + "pify": "^3.0.0" } }, "map-cache": { @@ -1752,7 +1756,7 @@ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { - "object-visit": "1.0.1" + "object-visit": "^1.0.0" } }, "media-typer": { @@ -1776,19 +1780,19 @@ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.13", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } }, "mime": { @@ -1806,7 +1810,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", "requires": { - "mime-db": "1.37.0" + "mime-db": "~1.37.0" } }, "minimatch": { @@ -1815,7 +1819,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -1825,13 +1829,13 @@ "dev": true }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "requires": { - "for-in": "1.0.2", - "is-extendable": "1.0.1" + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -1840,7 +1844,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -1851,9 +1855,9 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "nan": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", - "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", "dev": true, "optional": true }, @@ -1863,17 +1867,17 @@ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "fragment-cache": "0.2.1", - "is-windows": "1.0.2", - "kind-of": "6.0.2", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" } }, "negotiator": { @@ -1887,16 +1891,16 @@ "integrity": "sha512-xuC1V0F5EcEyKQ1VhHYD13owznQbUw29JKvZ8bVH7TmuvVNHvvbp9pLgE4PjTMRJVe0pJ8fGRvwR2nMiosIsPQ==", "dev": true, "requires": { - "chokidar": "2.0.4", - "debug": "3.2.6", - "ignore-by-default": "1.0.1", - "minimatch": "3.0.4", - "pstree.remy": "1.1.2", - "semver": "5.6.0", - "supports-color": "5.5.0", - "touch": "3.1.0", - "undefsafe": "2.0.2", - "update-notifier": "2.5.0" + "chokidar": "^2.0.4", + "debug": "^3.1.0", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.2", + "semver": "^5.5.0", + "supports-color": "^5.2.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.2", + "update-notifier": "^2.3.0" }, "dependencies": { "debug": { @@ -1905,7 +1909,7 @@ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "ms": { @@ -1922,17 +1926,14 @@ "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", "dev": true, "requires": { - "abbrev": "1.1.1" + "abbrev": "1" } }, "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "1.1.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "npm-run-path": { "version": "2.0.2", @@ -1940,7 +1941,7 @@ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, "requires": { - "path-key": "2.0.1" + "path-key": "^2.0.0" } }, "object-copy": { @@ -1949,9 +1950,9 @@ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { - "copy-descriptor": "0.1.1", - "define-property": "0.2.5", - "kind-of": "3.2.2" + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" }, "dependencies": { "define-property": { @@ -1960,7 +1961,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "kind-of": { @@ -1969,7 +1970,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1980,7 +1981,7 @@ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.0" } }, "object.pick": { @@ -1989,7 +1990,7 @@ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" } }, "on-finished": { @@ -2012,10 +2013,10 @@ "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", "dev": true, "requires": { - "got": "6.7.1", - "registry-auth-token": "3.3.2", - "registry-url": "3.1.0", - "semver": "5.6.0" + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" } }, "parseurl": { @@ -2077,9 +2078,9 @@ "dev": true }, "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, "proxy-addr": { @@ -2087,7 +2088,7 @@ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", "requires": { - "forwarded": "0.1.2", + "forwarded": "~0.1.2", "ipaddr.js": "1.8.0" } }, @@ -2130,10 +2131,10 @@ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, "requires": { - "deep-extend": "0.6.0", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" } }, "readable-stream": { @@ -2142,13 +2143,13 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "readdirp": { @@ -2157,9 +2158,9 @@ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "micromatch": "3.1.10", - "readable-stream": "2.3.6" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" } }, "regex-not": { @@ -2168,8 +2169,8 @@ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "requires": { - "extend-shallow": "3.0.2", - "safe-regex": "1.1.0" + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" } }, "registry-auth-token": { @@ -2178,8 +2179,8 @@ "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", "dev": true, "requires": { - "rc": "1.2.8", - "safe-buffer": "5.1.2" + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" } }, "registry-url": { @@ -2188,7 +2189,7 @@ "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", "dev": true, "requires": { - "rc": "1.2.8" + "rc": "^1.0.1" } }, "remove-trailing-separator": { @@ -2232,7 +2233,7 @@ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { - "ret": "0.1.15" + "ret": "~0.1.10" } }, "safer-buffer": { @@ -2252,7 +2253,7 @@ "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", "dev": true, "requires": { - "semver": "5.6.0" + "semver": "^5.0.3" } }, "send": { @@ -2261,18 +2262,18 @@ "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", "requires": { "debug": "2.6.9", - "depd": "1.1.2", - "destroy": "1.0.4", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.6.3", + "http-errors": "~1.6.2", "mime": "1.4.1", "ms": "2.0.0", - "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.4.0" + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" } }, "serve-static": { @@ -2280,22 +2281,22 @@ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", "requires": { - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "parseurl": "1.3.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", "send": "0.16.2" } }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "split-string": "3.1.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -2304,7 +2305,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -2320,7 +2321,7 @@ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { - "shebang-regex": "1.0.0" + "shebang-regex": "^1.0.0" } }, "shebang-regex": { @@ -2341,14 +2342,14 @@ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { - "base": "0.11.2", - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "map-cache": "0.2.2", - "source-map": "0.5.7", - "source-map-resolve": "0.5.2", - "use": "3.1.1" + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" }, "dependencies": { "define-property": { @@ -2357,7 +2358,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -2366,7 +2367,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -2377,9 +2378,9 @@ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "requires": { - "define-property": "1.0.0", - "isobject": "3.0.1", - "snapdragon-util": "3.0.1" + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" }, "dependencies": { "define-property": { @@ -2388,7 +2389,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -2397,7 +2398,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -2406,7 +2407,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -2415,9 +2416,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -2428,7 +2429,7 @@ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.2.0" }, "dependencies": { "kind-of": { @@ -2437,7 +2438,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -2454,11 +2455,11 @@ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "dev": true, "requires": { - "atob": "2.1.2", - "decode-uri-component": "0.2.0", - "resolve-url": "0.2.1", - "source-map-url": "0.4.0", - "urix": "0.1.0" + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" } }, "source-map-url": { @@ -2473,7 +2474,7 @@ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "requires": { - "extend-shallow": "3.0.2" + "extend-shallow": "^3.0.0" } }, "static-extend": { @@ -2482,8 +2483,8 @@ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { - "define-property": "0.2.5", - "object-copy": "0.1.0" + "define-property": "^0.2.5", + "object-copy": "^0.1.0" }, "dependencies": { "define-property": { @@ -2492,7 +2493,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -2508,8 +2509,8 @@ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" } }, "string_decoder": { @@ -2518,7 +2519,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { @@ -2527,7 +2528,7 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } }, "strip-eof": { @@ -2548,7 +2549,7 @@ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } }, "term-size": { @@ -2557,7 +2558,7 @@ "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", "dev": true, "requires": { - "execa": "0.7.0" + "execa": "^0.7.0" } }, "timed-out": { @@ -2572,7 +2573,7 @@ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -2581,7 +2582,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -2592,10 +2593,10 @@ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "regex-not": "1.0.2", - "safe-regex": "1.1.0" + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" } }, "to-regex-range": { @@ -2604,8 +2605,8 @@ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { - "is-number": "3.0.0", - "repeat-string": "1.6.1" + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" } }, "touch": { @@ -2614,7 +2615,7 @@ "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", "dev": true, "requires": { - "nopt": "1.0.10" + "nopt": "~1.0.10" } }, "type-is": { @@ -2623,7 +2624,7 @@ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", "requires": { "media-typer": "0.3.0", - "mime-types": "2.1.21" + "mime-types": "~2.1.18" } }, "undefsafe": { @@ -2632,42 +2633,19 @@ "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", "dev": true, "requires": { - "debug": "2.6.9" + "debug": "^2.2.0" } }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, "requires": { - "arr-union": "3.1.0", - "get-value": "2.0.6", - "is-extendable": "0.1.1", - "set-value": "0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "to-object-path": "0.3.0" - } - } + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" } }, "unique-string": { @@ -2676,7 +2654,7 @@ "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", "dev": true, "requires": { - "crypto-random-string": "1.0.0" + "crypto-random-string": "^1.0.0" } }, "unpipe": { @@ -2690,8 +2668,8 @@ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { - "has-value": "0.3.1", - "isobject": "3.0.1" + "has-value": "^0.3.1", + "isobject": "^3.0.0" }, "dependencies": { "has-value": { @@ -2700,9 +2678,9 @@ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "0.1.4", - "isobject": "2.1.0" + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" }, "dependencies": { "isobject": { @@ -2731,9 +2709,9 @@ "dev": true }, "upath": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", "dev": true }, "update-notifier": { @@ -2742,16 +2720,16 @@ "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", "dev": true, "requires": { - "boxen": "1.3.0", - "chalk": "2.4.1", - "configstore": "3.1.2", - "import-lazy": "2.1.0", - "is-ci": "1.2.1", - "is-installed-globally": "0.1.0", - "is-npm": "1.0.0", - "latest-version": "3.1.0", - "semver-diff": "2.1.0", - "xdg-basedir": "3.0.0" + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" } }, "urix": { @@ -2766,7 +2744,7 @@ "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", "dev": true, "requires": { - "prepend-http": "1.0.4" + "prepend-http": "^1.0.1" } }, "use": { @@ -2797,7 +2775,7 @@ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { - "isexe": "2.0.0" + "isexe": "^2.0.0" } }, "widest-line": { @@ -2806,7 +2784,7 @@ "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", "dev": true, "requires": { - "string-width": "2.1.1" + "string-width": "^2.1.1" } }, "write-file-atomic": { @@ -2815,9 +2793,9 @@ "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "imurmurhash": "0.1.4", - "signal-exit": "3.0.2" + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" } }, "xdg-basedir": { diff --git a/examples/hot-reload/node/package.json b/examples/hot-reload/node/package.json index 80ecc6e25dc..2de8036ec73 100644 --- a/examples/hot-reload/node/package.json +++ b/examples/hot-reload/node/package.json @@ -12,4 +12,4 @@ "devDependencies": { "nodemon": "^1.18.4" } -} \ No newline at end of file +} diff --git a/integration/examples/hot-reload/node/package-lock.json b/integration/examples/hot-reload/node/package-lock.json index a3ae06edb4d..2fdf304744f 100644 --- a/integration/examples/hot-reload/node/package-lock.json +++ b/integration/examples/hot-reload/node/package-lock.json @@ -15,7 +15,7 @@ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "requires": { - "mime-types": "2.1.21", + "mime-types": "~2.1.18", "negotiator": "0.6.1" } }, @@ -25,7 +25,7 @@ "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", "dev": true, "requires": { - "string-width": "2.1.1" + "string-width": "^2.0.0" } }, "ansi-regex": { @@ -40,7 +40,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.3" + "color-convert": "^1.9.0" } }, "anymatch": { @@ -49,8 +49,19 @@ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "micromatch": "3.1.10", - "normalize-path": "2.1.1" + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } } }, "arr-diff": { @@ -89,9 +100,9 @@ "dev": true }, "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", "dev": true }, "atob": { @@ -112,13 +123,13 @@ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { - "cache-base": "1.0.1", - "class-utils": "0.3.6", - "component-emitter": "1.2.1", - "define-property": "1.0.0", - "isobject": "3.0.1", - "mixin-deep": "1.3.1", - "pascalcase": "0.1.1" + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" }, "dependencies": { "define-property": { @@ -127,7 +138,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -136,7 +147,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -145,7 +156,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -154,17 +165,17 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } }, "binary-extensions": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", - "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, "body-parser": { @@ -173,15 +184,15 @@ "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", "requires": { "bytes": "3.0.0", - "content-type": "1.0.4", + "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "1.1.2", - "http-errors": "1.6.3", + "depd": "~1.1.2", + "http-errors": "~1.6.3", "iconv-lite": "0.4.23", - "on-finished": "2.3.0", + "on-finished": "~2.3.0", "qs": "6.5.2", "raw-body": "2.3.3", - "type-is": "1.6.16" + "type-is": "~1.6.16" } }, "boxen": { @@ -190,13 +201,13 @@ "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", "dev": true, "requires": { - "ansi-align": "2.0.0", - "camelcase": "4.1.0", - "chalk": "2.4.1", - "cli-boxes": "1.0.0", - "string-width": "2.1.1", - "term-size": "1.2.0", - "widest-line": "2.0.1" + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" } }, "brace-expansion": { @@ -205,7 +216,7 @@ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -215,16 +226,16 @@ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "repeat-element": "1.1.3", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -233,7 +244,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -249,15 +260,15 @@ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { - "collection-visit": "1.0.0", - "component-emitter": "1.2.1", - "get-value": "2.0.6", - "has-value": "1.0.0", - "isobject": "3.0.1", - "set-value": "2.0.0", - "to-object-path": "0.3.0", - "union-value": "1.0.0", - "unset-value": "1.0.0" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" } }, "camelcase": { @@ -278,30 +289,29 @@ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.5.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", "dev": true, "requires": { - "anymatch": "2.0.0", - "async-each": "1.0.1", - "braces": "2.3.2", - "fsevents": "1.2.4", - "glob-parent": "3.1.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "4.0.0", - "lodash.debounce": "4.0.8", - "normalize-path": "2.1.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.2.1", - "upath": "1.1.0" + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" } }, "ci-info": { @@ -316,10 +326,10 @@ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { - "arr-union": "3.1.0", - "define-property": "0.2.5", - "isobject": "3.0.1", - "static-extend": "0.1.2" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, "dependencies": { "define-property": { @@ -328,7 +338,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -345,8 +355,8 @@ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { - "map-visit": "1.0.0", - "object-visit": "1.0.1" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, "color-convert": { @@ -365,9 +375,9 @@ "dev": true }, "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, "concat-map": { @@ -382,12 +392,12 @@ "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", "dev": true, "requires": { - "dot-prop": "4.2.0", - "graceful-fs": "4.1.15", - "make-dir": "1.3.0", - "unique-string": "1.0.0", - "write-file-atomic": "2.3.0", - "xdg-basedir": "3.0.0" + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" } }, "content-disposition": { @@ -428,7 +438,7 @@ "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", "dev": true, "requires": { - "capture-stack-trace": "1.0.1" + "capture-stack-trace": "^1.0.0" } }, "cross-spawn": { @@ -437,9 +447,9 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "4.1.4", - "shebang-command": "1.2.0", - "which": "1.3.1" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "crypto-random-string": { @@ -474,8 +484,8 @@ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { - "is-descriptor": "1.0.2", - "isobject": "3.0.1" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "dependencies": { "is-accessor-descriptor": { @@ -484,7 +494,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -493,7 +503,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -502,9 +512,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -525,7 +535,7 @@ "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", "dev": true, "requires": { - "is-obj": "1.0.1" + "is-obj": "^1.0.0" } }, "duplexer3": { @@ -566,13 +576,13 @@ "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "dev": true, "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" } }, "expand-brackets": { @@ -581,13 +591,13 @@ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -596,7 +606,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -605,7 +615,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -615,36 +625,36 @@ "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", "requires": { - "accepts": "1.3.5", + "accepts": "~1.3.5", "array-flatten": "1.1.1", "body-parser": "1.18.3", "content-disposition": "0.5.2", - "content-type": "1.0.4", + "content-type": "~1.0.4", "cookie": "0.3.1", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "1.1.2", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "finalhandler": "1.1.1", "fresh": "0.5.2", "merge-descriptors": "1.0.1", - "methods": "1.1.2", - "on-finished": "2.3.0", - "parseurl": "1.3.2", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", "path-to-regexp": "0.1.7", - "proxy-addr": "2.0.4", + "proxy-addr": "~2.0.4", "qs": "6.5.2", - "range-parser": "1.2.0", + "range-parser": "~1.2.0", "safe-buffer": "5.1.2", "send": "0.16.2", "serve-static": "1.13.2", "setprototypeof": "1.1.0", - "statuses": "1.4.0", - "type-is": "1.6.16", + "statuses": "~1.4.0", + "type-is": "~1.6.16", "utils-merge": "1.0.1", - "vary": "1.1.2" + "vary": "~1.1.2" } }, "extend-shallow": { @@ -653,8 +663,8 @@ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { - "assign-symbols": "1.0.0", - "is-extendable": "1.0.1" + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -663,7 +673,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -674,14 +684,14 @@ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -690,7 +700,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "extend-shallow": { @@ -699,7 +709,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "is-accessor-descriptor": { @@ -708,7 +718,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -717,7 +727,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -726,9 +736,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -739,10 +749,10 @@ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "dependencies": { "extend-shallow": { @@ -751,7 +761,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -762,12 +772,12 @@ "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "requires": { "debug": "2.6.9", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "statuses": "1.4.0", - "unpipe": "1.0.0" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" } }, "for-in": { @@ -787,7 +797,7 @@ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { - "map-cache": "0.2.2" + "map-cache": "^0.2.2" } }, "fresh": { @@ -796,14 +806,14 @@ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", "dev": true, "optional": true, "requires": { - "nan": "2.11.1", - "node-pre-gyp": "0.10.0" + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" }, "dependencies": { "abbrev": { @@ -824,13 +834,13 @@ "optional": true }, "are-we-there-yet": { - "version": "1.1.4", + "version": "1.1.5", "bundled": true, "dev": true, "optional": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.6" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, "balanced-match": { @@ -843,12 +853,12 @@ "bundled": true, "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "chownr": { - "version": "1.0.1", + "version": "1.1.1", "bundled": true, "dev": true, "optional": true @@ -875,16 +885,16 @@ "optional": true }, "debug": { - "version": "2.6.9", + "version": "4.1.1", "bundled": true, "dev": true, "optional": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "deep-extend": { - "version": "0.5.1", + "version": "0.6.0", "bundled": true, "dev": true, "optional": true @@ -907,7 +917,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "fs.realpath": { @@ -922,28 +932,28 @@ "dev": true, "optional": true, "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } }, "glob": { - "version": "7.1.2", + "version": "7.1.3", "bundled": true, "dev": true, "optional": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "has-unicode": { @@ -953,12 +963,12 @@ "optional": true }, "iconv-lite": { - "version": "0.4.21", + "version": "0.4.24", "bundled": true, "dev": true, "optional": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore-walk": { @@ -967,7 +977,7 @@ "dev": true, "optional": true, "requires": { - "minimatch": "3.0.4" + "minimatch": "^3.0.4" } }, "inflight": { @@ -976,8 +986,8 @@ "dev": true, "optional": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -996,7 +1006,7 @@ "bundled": true, "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "isarray": { @@ -1010,7 +1020,7 @@ "bundled": true, "dev": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -1019,21 +1029,21 @@ "dev": true }, "minipass": { - "version": "2.2.4", + "version": "2.3.5", "bundled": true, "dev": true, "requires": { - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" } }, "minizlib": { - "version": "1.1.0", + "version": "1.2.1", "bundled": true, "dev": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "mkdirp": { @@ -1045,38 +1055,38 @@ } }, "ms": { - "version": "2.0.0", + "version": "2.1.1", "bundled": true, "dev": true, "optional": true }, "needle": { - "version": "2.2.0", + "version": "2.3.0", "bundled": true, "dev": true, "optional": true, "requires": { - "debug": "2.6.9", - "iconv-lite": "0.4.21", - "sax": "1.2.4" + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" } }, "node-pre-gyp": { - "version": "0.10.0", + "version": "0.12.0", "bundled": true, "dev": true, "optional": true, "requires": { - "detect-libc": "1.0.3", - "mkdirp": "0.5.1", - "needle": "2.2.0", - "nopt": "4.0.1", - "npm-packlist": "1.1.10", - "npmlog": "4.1.2", - "rc": "1.2.7", - "rimraf": "2.6.2", - "semver": "5.5.0", - "tar": "4.4.1" + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" } }, "nopt": { @@ -1085,24 +1095,24 @@ "dev": true, "optional": true, "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.5" + "abbrev": "1", + "osenv": "^0.1.4" } }, "npm-bundled": { - "version": "1.0.3", + "version": "1.0.6", "bundled": true, "dev": true, "optional": true }, "npm-packlist": { - "version": "1.1.10", + "version": "1.4.1", "bundled": true, "dev": true, "optional": true, "requires": { - "ignore-walk": "3.0.1", - "npm-bundled": "1.0.3" + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" } }, "npmlog": { @@ -1111,10 +1121,10 @@ "dev": true, "optional": true, "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "number-is-nan": { @@ -1133,7 +1143,7 @@ "bundled": true, "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "os-homedir": { @@ -1154,8 +1164,8 @@ "dev": true, "optional": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "path-is-absolute": { @@ -1171,15 +1181,15 @@ "optional": true }, "rc": { - "version": "1.2.7", + "version": "1.2.8", "bundled": true, "dev": true, "optional": true, "requires": { - "deep-extend": "0.5.1", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { "minimist": { @@ -1196,26 +1206,26 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "rimraf": { - "version": "2.6.2", + "version": "2.6.3", "bundled": true, "dev": true, "optional": true, "requires": { - "glob": "7.1.2" + "glob": "^7.1.3" } }, "safe-buffer": { - "version": "5.1.1", + "version": "5.1.2", "bundled": true, "dev": true }, @@ -1232,7 +1242,7 @@ "optional": true }, "semver": { - "version": "5.5.0", + "version": "5.7.0", "bundled": true, "dev": true, "optional": true @@ -1254,9 +1264,9 @@ "bundled": true, "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { @@ -1265,7 +1275,7 @@ "dev": true, "optional": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { @@ -1273,7 +1283,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-json-comments": { @@ -1283,18 +1293,18 @@ "optional": true }, "tar": { - "version": "4.4.1", + "version": "4.4.8", "bundled": true, "dev": true, "optional": true, "requires": { - "chownr": "1.0.1", - "fs-minipass": "1.2.5", - "minipass": "2.2.4", - "minizlib": "1.1.0", - "mkdirp": "0.5.1", - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" } }, "util-deprecate": { @@ -1304,12 +1314,12 @@ "optional": true }, "wide-align": { - "version": "1.1.2", + "version": "1.1.3", "bundled": true, "dev": true, "optional": true, "requires": { - "string-width": "1.0.2" + "string-width": "^1.0.2 || 2" } }, "wrappy": { @@ -1318,7 +1328,7 @@ "dev": true }, "yallist": { - "version": "3.0.2", + "version": "3.0.3", "bundled": true, "dev": true } @@ -1342,8 +1352,8 @@ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" }, "dependencies": { "is-glob": { @@ -1352,7 +1362,7 @@ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.0" } } } @@ -1363,7 +1373,7 @@ "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", "dev": true, "requires": { - "ini": "1.3.5" + "ini": "^1.3.4" } }, "got": { @@ -1372,17 +1382,17 @@ "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", "dev": true, "requires": { - "create-error-class": "3.0.2", - "duplexer3": "0.1.4", - "get-stream": "3.0.0", - "is-redirect": "1.0.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "lowercase-keys": "1.0.1", - "safe-buffer": "5.1.2", - "timed-out": "4.0.1", - "unzip-response": "2.0.1", - "url-parse-lax": "1.0.0" + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" } }, "graceful-fs": { @@ -1403,9 +1413,9 @@ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "1.0.0", - "isobject": "3.0.1" + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" } }, "has-values": { @@ -1414,8 +1424,8 @@ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "dependencies": { "kind-of": { @@ -1424,7 +1434,7 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1434,10 +1444,10 @@ "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "requires": { - "depd": "1.1.2", + "depd": "~1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.0", - "statuses": "1.4.0" + "statuses": ">= 1.4.0 < 2" } }, "iconv-lite": { @@ -1445,7 +1455,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore-by-default": { @@ -1488,7 +1498,7 @@ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -1497,7 +1507,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1508,7 +1518,7 @@ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "1.12.0" + "binary-extensions": "^1.0.0" } }, "is-buffer": { @@ -1523,7 +1533,7 @@ "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", "dev": true, "requires": { - "ci-info": "1.6.0" + "ci-info": "^1.5.0" } }, "is-data-descriptor": { @@ -1532,7 +1542,7 @@ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -1541,7 +1551,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1552,9 +1562,9 @@ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" }, "dependencies": { "kind-of": { @@ -1584,12 +1594,12 @@ "dev": true }, "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.1" } }, "is-installed-globally": { @@ -1598,8 +1608,8 @@ "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", "dev": true, "requires": { - "global-dirs": "0.1.1", - "is-path-inside": "1.0.1" + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" } }, "is-npm": { @@ -1614,7 +1624,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -1623,7 +1633,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1640,7 +1650,7 @@ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "dev": true, "requires": { - "path-is-inside": "1.0.2" + "path-is-inside": "^1.0.1" } }, "is-plain-object": { @@ -1649,7 +1659,7 @@ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" } }, "is-redirect": { @@ -1706,15 +1716,9 @@ "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", "dev": true, "requires": { - "package-json": "4.0.1" + "package-json": "^4.0.0" } }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -1727,8 +1731,8 @@ "integrity": "sha512-EPstzZ23znHUVLKj+lcXO1KvZkrlw+ZirdwvOmnAnA/1PB4ggyXJ77LRkCqkff+ShQ+cqoxCxLQOh4cKITO5iA==", "dev": true, "requires": { - "pseudomap": "1.0.2", - "yallist": "3.0.3" + "pseudomap": "^1.0.2", + "yallist": "^3.0.2" } }, "make-dir": { @@ -1737,7 +1741,7 @@ "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, "requires": { - "pify": "3.0.0" + "pify": "^3.0.0" } }, "map-cache": { @@ -1752,7 +1756,7 @@ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { - "object-visit": "1.0.1" + "object-visit": "^1.0.0" } }, "media-typer": { @@ -1776,19 +1780,19 @@ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.13", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } }, "mime": { @@ -1806,7 +1810,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", "requires": { - "mime-db": "1.37.0" + "mime-db": "~1.37.0" } }, "minimatch": { @@ -1815,7 +1819,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -1825,13 +1829,13 @@ "dev": true }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "requires": { - "for-in": "1.0.2", - "is-extendable": "1.0.1" + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -1840,7 +1844,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -1851,9 +1855,9 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "nan": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", - "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", "dev": true, "optional": true }, @@ -1863,17 +1867,17 @@ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "fragment-cache": "0.2.1", - "is-windows": "1.0.2", - "kind-of": "6.0.2", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" } }, "negotiator": { @@ -1887,16 +1891,16 @@ "integrity": "sha512-xuC1V0F5EcEyKQ1VhHYD13owznQbUw29JKvZ8bVH7TmuvVNHvvbp9pLgE4PjTMRJVe0pJ8fGRvwR2nMiosIsPQ==", "dev": true, "requires": { - "chokidar": "2.0.4", - "debug": "3.2.6", - "ignore-by-default": "1.0.1", - "minimatch": "3.0.4", - "pstree.remy": "1.1.2", - "semver": "5.6.0", - "supports-color": "5.5.0", - "touch": "3.1.0", - "undefsafe": "2.0.2", - "update-notifier": "2.5.0" + "chokidar": "^2.0.4", + "debug": "^3.1.0", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.2", + "semver": "^5.5.0", + "supports-color": "^5.2.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.2", + "update-notifier": "^2.3.0" }, "dependencies": { "debug": { @@ -1905,7 +1909,7 @@ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "ms": { @@ -1922,17 +1926,14 @@ "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", "dev": true, "requires": { - "abbrev": "1.1.1" + "abbrev": "1" } }, "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "1.1.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "npm-run-path": { "version": "2.0.2", @@ -1940,7 +1941,7 @@ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, "requires": { - "path-key": "2.0.1" + "path-key": "^2.0.0" } }, "object-copy": { @@ -1949,9 +1950,9 @@ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { - "copy-descriptor": "0.1.1", - "define-property": "0.2.5", - "kind-of": "3.2.2" + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" }, "dependencies": { "define-property": { @@ -1960,7 +1961,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "kind-of": { @@ -1969,7 +1970,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1980,7 +1981,7 @@ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.0" } }, "object.pick": { @@ -1989,7 +1990,7 @@ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" } }, "on-finished": { @@ -2012,10 +2013,10 @@ "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", "dev": true, "requires": { - "got": "6.7.1", - "registry-auth-token": "3.3.2", - "registry-url": "3.1.0", - "semver": "5.6.0" + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" } }, "parseurl": { @@ -2077,9 +2078,9 @@ "dev": true }, "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, "proxy-addr": { @@ -2087,7 +2088,7 @@ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", "requires": { - "forwarded": "0.1.2", + "forwarded": "~0.1.2", "ipaddr.js": "1.8.0" } }, @@ -2130,10 +2131,10 @@ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, "requires": { - "deep-extend": "0.6.0", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" } }, "readable-stream": { @@ -2142,13 +2143,13 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "readdirp": { @@ -2157,9 +2158,9 @@ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "micromatch": "3.1.10", - "readable-stream": "2.3.6" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" } }, "regex-not": { @@ -2168,8 +2169,8 @@ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "requires": { - "extend-shallow": "3.0.2", - "safe-regex": "1.1.0" + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" } }, "registry-auth-token": { @@ -2178,8 +2179,8 @@ "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", "dev": true, "requires": { - "rc": "1.2.8", - "safe-buffer": "5.1.2" + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" } }, "registry-url": { @@ -2188,7 +2189,7 @@ "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", "dev": true, "requires": { - "rc": "1.2.8" + "rc": "^1.0.1" } }, "remove-trailing-separator": { @@ -2232,7 +2233,7 @@ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { - "ret": "0.1.15" + "ret": "~0.1.10" } }, "safer-buffer": { @@ -2252,7 +2253,7 @@ "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", "dev": true, "requires": { - "semver": "5.6.0" + "semver": "^5.0.3" } }, "send": { @@ -2261,18 +2262,18 @@ "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", "requires": { "debug": "2.6.9", - "depd": "1.1.2", - "destroy": "1.0.4", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.6.3", + "http-errors": "~1.6.2", "mime": "1.4.1", "ms": "2.0.0", - "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.4.0" + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" } }, "serve-static": { @@ -2280,22 +2281,22 @@ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", "requires": { - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "parseurl": "1.3.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", "send": "0.16.2" } }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "split-string": "3.1.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -2304,7 +2305,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -2320,7 +2321,7 @@ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { - "shebang-regex": "1.0.0" + "shebang-regex": "^1.0.0" } }, "shebang-regex": { @@ -2341,14 +2342,14 @@ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { - "base": "0.11.2", - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "map-cache": "0.2.2", - "source-map": "0.5.7", - "source-map-resolve": "0.5.2", - "use": "3.1.1" + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" }, "dependencies": { "define-property": { @@ -2357,7 +2358,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -2366,7 +2367,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -2377,9 +2378,9 @@ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "requires": { - "define-property": "1.0.0", - "isobject": "3.0.1", - "snapdragon-util": "3.0.1" + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" }, "dependencies": { "define-property": { @@ -2388,7 +2389,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -2397,7 +2398,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -2406,7 +2407,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -2415,9 +2416,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -2428,7 +2429,7 @@ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.2.0" }, "dependencies": { "kind-of": { @@ -2437,7 +2438,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -2454,11 +2455,11 @@ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "dev": true, "requires": { - "atob": "2.1.2", - "decode-uri-component": "0.2.0", - "resolve-url": "0.2.1", - "source-map-url": "0.4.0", - "urix": "0.1.0" + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" } }, "source-map-url": { @@ -2473,7 +2474,7 @@ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "requires": { - "extend-shallow": "3.0.2" + "extend-shallow": "^3.0.0" } }, "static-extend": { @@ -2482,8 +2483,8 @@ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { - "define-property": "0.2.5", - "object-copy": "0.1.0" + "define-property": "^0.2.5", + "object-copy": "^0.1.0" }, "dependencies": { "define-property": { @@ -2492,7 +2493,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -2508,8 +2509,8 @@ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" } }, "string_decoder": { @@ -2518,7 +2519,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { @@ -2527,7 +2528,7 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } }, "strip-eof": { @@ -2548,7 +2549,7 @@ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } }, "term-size": { @@ -2557,7 +2558,7 @@ "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", "dev": true, "requires": { - "execa": "0.7.0" + "execa": "^0.7.0" } }, "timed-out": { @@ -2572,7 +2573,7 @@ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -2581,7 +2582,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -2592,10 +2593,10 @@ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "regex-not": "1.0.2", - "safe-regex": "1.1.0" + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" } }, "to-regex-range": { @@ -2604,8 +2605,8 @@ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { - "is-number": "3.0.0", - "repeat-string": "1.6.1" + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" } }, "touch": { @@ -2614,7 +2615,7 @@ "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", "dev": true, "requires": { - "nopt": "1.0.10" + "nopt": "~1.0.10" } }, "type-is": { @@ -2623,7 +2624,7 @@ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", "requires": { "media-typer": "0.3.0", - "mime-types": "2.1.21" + "mime-types": "~2.1.18" } }, "undefsafe": { @@ -2632,42 +2633,19 @@ "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", "dev": true, "requires": { - "debug": "2.6.9" + "debug": "^2.2.0" } }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, "requires": { - "arr-union": "3.1.0", - "get-value": "2.0.6", - "is-extendable": "0.1.1", - "set-value": "0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "to-object-path": "0.3.0" - } - } + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" } }, "unique-string": { @@ -2676,7 +2654,7 @@ "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", "dev": true, "requires": { - "crypto-random-string": "1.0.0" + "crypto-random-string": "^1.0.0" } }, "unpipe": { @@ -2690,8 +2668,8 @@ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { - "has-value": "0.3.1", - "isobject": "3.0.1" + "has-value": "^0.3.1", + "isobject": "^3.0.0" }, "dependencies": { "has-value": { @@ -2700,9 +2678,9 @@ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "0.1.4", - "isobject": "2.1.0" + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" }, "dependencies": { "isobject": { @@ -2731,9 +2709,9 @@ "dev": true }, "upath": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", "dev": true }, "update-notifier": { @@ -2742,16 +2720,16 @@ "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", "dev": true, "requires": { - "boxen": "1.3.0", - "chalk": "2.4.1", - "configstore": "3.1.2", - "import-lazy": "2.1.0", - "is-ci": "1.2.1", - "is-installed-globally": "0.1.0", - "is-npm": "1.0.0", - "latest-version": "3.1.0", - "semver-diff": "2.1.0", - "xdg-basedir": "3.0.0" + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" } }, "urix": { @@ -2766,7 +2744,7 @@ "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", "dev": true, "requires": { - "prepend-http": "1.0.4" + "prepend-http": "^1.0.1" } }, "use": { @@ -2797,7 +2775,7 @@ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { - "isexe": "2.0.0" + "isexe": "^2.0.0" } }, "widest-line": { @@ -2806,7 +2784,7 @@ "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", "dev": true, "requires": { - "string-width": "2.1.1" + "string-width": "^2.1.1" } }, "write-file-atomic": { @@ -2815,9 +2793,9 @@ "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "imurmurhash": "0.1.4", - "signal-exit": "3.0.2" + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" } }, "xdg-basedir": { diff --git a/integration/examples/hot-reload/node/package.json b/integration/examples/hot-reload/node/package.json index 80ecc6e25dc..2de8036ec73 100644 --- a/integration/examples/hot-reload/node/package.json +++ b/integration/examples/hot-reload/node/package.json @@ -12,4 +12,4 @@ "devDependencies": { "nodemon": "^1.18.4" } -} \ No newline at end of file +} From 13a5d595d7bcc760d00460e80dd78fa0f676d1ac Mon Sep 17 00:00:00 2001 From: David Gageot Date: Fri, 30 Aug 2019 07:07:12 +0200 Subject: [PATCH 69/69] Add logs when listing files to be watched (#2743) Fixes #2742 Signed-off-by: David Gageot --- pkg/skaffold/runner/dev.go | 44 ++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/pkg/skaffold/runner/dev.go b/pkg/skaffold/runner/dev.go index 503cdbfeab8..64a7f602973 100644 --- a/pkg/skaffold/runner/dev.go +++ b/pkg/skaffold/runner/dev.go @@ -120,28 +120,38 @@ func (r *SkaffoldRunner) Dev(ctx context.Context, out io.Writer, artifacts []*la defer r.forwarderManager.Stop() // Watch artifacts + start := time.Now() + color.Default.Fprintln(out, "Listing files to watch...") + for i := range artifacts { artifact := artifacts[i] if !r.runCtx.Opts.IsTargetImage(artifact) { continue } - if err := r.monitor.Register( - func() ([]string, error) { return r.builder.DependenciesForArtifact(ctx, artifact) }, - func(e filemon.Events) { - syncMap := func() (map[string][]string, error) { return r.builder.SyncMap(ctx, artifact) } - s, err := sync.NewItem(artifact, e, r.builds, r.runCtx.InsecureRegistries, syncMap) - switch { - case err != nil: - logrus.Warnf("error adding dirty artifact to changeset: %s", err.Error()) - case s != nil: - r.changeSet.AddResync(s) - default: - r.changeSet.AddRebuild(artifact) - } - }, - ); err != nil { - return errors.Wrapf(err, "watching files for artifact %s", artifact.ImageName) + color.Default.Fprintf(out, " - %s\n", artifact.ImageName) + + select { + case <-ctx.Done(): + return context.Canceled + default: + if err := r.monitor.Register( + func() ([]string, error) { return r.builder.DependenciesForArtifact(ctx, artifact) }, + func(e filemon.Events) { + syncMap := func() (map[string][]string, error) { return r.builder.SyncMap(ctx, artifact) } + s, err := sync.NewItem(artifact, e, r.builds, r.runCtx.InsecureRegistries, syncMap) + switch { + case err != nil: + logrus.Warnf("error adding dirty artifact to changeset: %s", err.Error()) + case s != nil: + r.changeSet.AddResync(s) + default: + r.changeSet.AddRebuild(artifact) + } + }, + ); err != nil { + return errors.Wrapf(err, "watching files for artifact %s", artifact.ImageName) + } } } @@ -169,6 +179,8 @@ func (r *SkaffoldRunner) Dev(ctx context.Context, out io.Writer, artifacts []*la return errors.Wrapf(err, "watching skaffold configuration %s", r.runCtx.Opts.ConfigurationFile) } + color.Default.Fprintln(out, "List generated in", time.Since(start)) + // First build if _, err := r.BuildAndTest(ctx, out, artifacts); err != nil { return errors.Wrap(err, "exiting dev mode because first build failed")