github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/cli/patch.go (about)

     1  /*
     2  Adapted from
     3  https://github.com/kubernetes/kubectl/tree/master/pkg/cmd/patch
     4  */
     5  
     6  /*
     7  Copyright 2014 The Kubernetes Authors.
     8  
     9  Licensed under the Apache License, Version 2.0 (the "License");
    10  you may not use this file except in compliance with the License.
    11  You may obtain a copy of the License at
    12  
    13      http://www.apache.org/licenses/LICENSE-2.0
    14  
    15  Unless required by applicable law or agreed to in writing, software
    16  distributed under the License is distributed on an "AS IS" BASIS,
    17  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    18  See the License for the specific language governing permissions and
    19  limitations under the License.
    20  */
    21  
    22  package cli
    23  
    24  import (
    25  	"context"
    26  	"fmt"
    27  	"time"
    28  
    29  	"github.com/spf13/cobra"
    30  	"k8s.io/apimachinery/pkg/types"
    31  	"k8s.io/apimachinery/pkg/util/sets"
    32  	"k8s.io/cli-runtime/pkg/genericclioptions"
    33  	"k8s.io/kubectl/pkg/cmd/patch"
    34  	cmdutil "k8s.io/kubectl/pkg/cmd/util"
    35  
    36  	"github.com/tilt-dev/tilt/internal/analytics"
    37  	engineanalytics "github.com/tilt-dev/tilt/internal/engine/analytics"
    38  	"github.com/tilt-dev/tilt/pkg/model"
    39  )
    40  
    41  var patchTypes = map[string]types.PatchType{"json": types.JSONPatchType, "merge": types.MergePatchType, "strategic": types.StrategicMergePatchType}
    42  
    43  var (
    44  	patchLong = `
    45  		Update fields of a resource using strategic merge patch, a JSON merge patch, or a JSON patch.
    46  		JSON and YAML formats are accepted.
    47  
    48      Uses the same semantics as 'kubectl patch':
    49      https://kubernetes.io/docs/reference/kubectl/cheatsheet/#patching-resources
    50  `
    51  )
    52  
    53  type patchCmd struct {
    54  	streams genericclioptions.IOStreams
    55  	options *patch.PatchOptions
    56  	cmd     *cobra.Command
    57  }
    58  
    59  var _ tiltCmd = &patchCmd{}
    60  
    61  func newPatchCmd(streams genericclioptions.IOStreams) *patchCmd {
    62  	return &patchCmd{
    63  		streams: streams,
    64  	}
    65  }
    66  
    67  func (c *patchCmd) name() model.TiltSubcommand { return "patch" }
    68  
    69  func (c *patchCmd) register() *cobra.Command {
    70  	o := patch.NewPatchOptions(c.streams)
    71  
    72  	cmd := &cobra.Command{
    73  		Use:                   "patch (-f FILENAME | TYPE NAME) [-p PATCH|--patch-file FILE]",
    74  		DisableFlagsInUseLine: true,
    75  		Short:                 "Update fields of a resource",
    76  		Long:                  patchLong,
    77  	}
    78  
    79  	o.RecordFlags.AddFlags(cmd)
    80  	o.PrintFlags.AddFlags(cmd)
    81  
    82  	cmd.Flags().StringVarP(&o.Patch, "patch", "p", "", "The patch to be applied to the resource JSON file.")
    83  	cmd.Flags().StringVar(&o.PatchFile, "patch-file", "", "A file containing a patch to be applied to the resource.")
    84  	cmd.Flags().StringVar(&o.PatchType, "type", "strategic", fmt.Sprintf("The type of patch being provided; one of %v", sets.StringKeySet(patchTypes).List()))
    85  	cmdutil.AddDryRunFlag(cmd)
    86  	cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, "identifying the resource to update")
    87  	cmd.Flags().BoolVar(&o.Local, "local", o.Local, "If true, patch will operate on the content of the file, not the server-side resource.")
    88  	addConnectServerFlags(cmd)
    89  
    90  	c.cmd = cmd
    91  	c.options = o
    92  	return cmd
    93  }
    94  
    95  func (c *patchCmd) run(ctx context.Context, args []string) error {
    96  	a := analytics.Get(ctx)
    97  	cmdTags := engineanalytics.CmdTags(map[string]string{})
    98  	a.Incr("cmd.patch", cmdTags.AsMap())
    99  	defer a.Flush(time.Second)
   100  
   101  	getter, err := wireClientGetter(ctx)
   102  	if err != nil {
   103  		return err
   104  	}
   105  
   106  	f := cmdutil.NewFactory(getter)
   107  	cmd := c.cmd
   108  	o := c.options
   109  
   110  	cmdutil.CheckErr(o.Complete(f, cmd, args))
   111  	cmdutil.CheckErr(o.Validate())
   112  	cmdutil.CheckErr(o.RunPatch())
   113  	return nil
   114  }