diff --git a/cmd/crossplane/config/config.go b/cmd/crossplane/config/config.go index dc8f1be..d73b969 100644 --- a/cmd/crossplane/config/config.go +++ b/cmd/crossplane/config/config.go @@ -17,6 +17,11 @@ limitations under the License. // Package config contains the `crossplane config` subcommands. package config +import _ "embed" + +//go:embed help/config.md +var helpDetail string + // ConfigPath is the resolved config file path. It is bound by main so that // subcommands can receive it as a Run() argument. Using a typed alias keeps // the binding distinct from any other string value Kong may know about. @@ -31,19 +36,5 @@ type Cmd struct { // Help returns the extended help for the config command. func (c *Cmd) Help() string { - return ` -Manage the crossplane CLI configuration file. - -The config file location is, in priority order: - 1. The --config flag. - 2. The CROSSPLANE_CONFIG environment variable. - 3. $XDG_CONFIG_HOME/crossplane/config.yaml (or ~/.config/crossplane/config.yaml). - -Examples: - # Show the current effective config. - crossplane config view - - # Enable alpha commands. - crossplane config set features.enableAlpha true -` + return helpDetail } diff --git a/cmd/crossplane/config/help/config.md b/cmd/crossplane/config/help/config.md new file mode 100644 index 0000000..91f2e07 --- /dev/null +++ b/cmd/crossplane/config/help/config.md @@ -0,0 +1,20 @@ +The `config` command manages the configuration file for the `crossplane` +CLI. The config file location is, in priority order: + +1. The `--config` flag. +2. The `CROSSPLANE_CONFIG` environment variable. +3. `$XDG_CONFIG_HOME/crossplane/config.yaml` (or `~/.config/crossplane/config.yaml`). + +## Examples + +Show the current effective config: + +```shell +crossplane config view +``` + +Enable alpha commands: + +```shell +crossplane config set features.enableAlpha true +``` diff --git a/cmd/crossplane/convert/compositionenvironment/cmd.go b/cmd/crossplane/convert/compositionenvironment/cmd.go index a5850ef..82a38cb 100644 --- a/cmd/crossplane/convert/compositionenvironment/cmd.go +++ b/cmd/crossplane/convert/compositionenvironment/cmd.go @@ -31,8 +31,13 @@ import ( "github.com/crossplane/crossplane-runtime/v2/pkg/errors" commonIO "github.com/crossplane/cli/v2/cmd/crossplane/convert/io" + + _ "embed" ) +//go:embed help/composition-environment.md +var helpDetail string + // Cmd arguments and flags for converting a Composition to use function-environment-configs. type Cmd struct { // Arguments. @@ -48,26 +53,7 @@ type Cmd struct { // Help returns help message for the migrate composition-environment command. func (c *Cmd) Help() string { - return ` -This command converts a Crossplane Composition to use function-environment-configs, if needed. - -It adds a function pipeline step using crossplane-contrib/function-environment-configs, if needed. -By default it'll reference the function as function-environment-configs, but it can be overridden -with the -f flag. - -Examples: - - # Convert an existing Composition (Pipeline mode) leveraging native - # Composition Environment to use function-environment-configs. - crossplane composition convert composition-environment composition.yaml -o composition-environment.yaml - - # Use a different functionRef and output to stdout. - crossplane composition convert composition-environment composition.yaml --function-environment-configs-ref local-function-environment-configs - - # Stdin to stdout. - cat composition.yaml | ./crossplane composition convert composition-environment - -` + return helpDetail } // AfterApply implements kong.AfterApply. diff --git a/cmd/crossplane/convert/compositionenvironment/help/composition-environment.md b/cmd/crossplane/convert/compositionenvironment/help/composition-environment.md new file mode 100644 index 0000000..8e0a206 --- /dev/null +++ b/cmd/crossplane/convert/compositionenvironment/help/composition-environment.md @@ -0,0 +1,31 @@ +The `composition convert composition-environment` command converts a Crossplane +Composition to use `function-environment-configs` in place of native Composition +Environments, which were removed in Crossplane v1.18. + +It adds a function pipeline step using +`crossplane-contrib/function-environment-configs` if needed. By default the +function is referenced as `function-environment-configs`, but this can be +overridden with `--function-environment-configs-ref`. + +## Examples + +Convert an existing pipeline mode Composition using native Composition +Environment to `function-environment-configs`: + +```shell +crossplane composition convert composition-environment composition.yaml \ + -o composition-environment.yaml +``` + +Use a different functionRef and output to stdout: + +```shell +crossplane composition convert composition-environment composition.yaml \ + --function-environment-configs-ref=local-function-environment-configs +``` + +Read a composition from stdin and output the updated composition on stdout: + +```shell +cat composition.yaml | crossplane composition convert composition-environment +``` diff --git a/cmd/crossplane/convert/convert.go b/cmd/crossplane/convert/convert.go index 35e1770..c2b6c62 100644 --- a/cmd/crossplane/convert/convert.go +++ b/cmd/crossplane/convert/convert.go @@ -20,8 +20,13 @@ package convert import ( "github.com/crossplane/cli/v2/cmd/crossplane/convert/compositionenvironment" + + _ "embed" ) +//go:embed help/convert.md +var helpDetail string + // Cmd converts a Crossplane resource to a newer version or a different kind. type Cmd struct { CompositionEnvironment compositionenvironment.Cmd `cmd:"" help:"Convert a Pipeline Composition to use function-environment-configs."` @@ -29,15 +34,5 @@ type Cmd struct { // Help returns help message for the migrate command. func (c *Cmd) Help() string { - return ` -This command converts a Crossplane resource to a newer version or a different kind. - -Currently supported conversions: - * native Composition Environment -> function-environment-configs - -Examples: - # Convert an existing Composition to use function-environment-configs instead of native Composition Environment, - # requires the composition to be in Pipeline mode already. - crossplane composition convert composition-environment composition.yaml -o composition-environment.yaml -` + return helpDetail } diff --git a/cmd/crossplane/convert/help/convert.md b/cmd/crossplane/convert/help/convert.md new file mode 100644 index 0000000..6cd5f5e --- /dev/null +++ b/cmd/crossplane/convert/help/convert.md @@ -0,0 +1,6 @@ +The `composition convert` command converts a Crossplane composition to use a +different version or migrate away from features that are no longer supported. + +The currently supported conversions are: + +- Native Composition Environment → `function-environment-configs` diff --git a/cmd/crossplane/docs-templates/command-reference.md.tmpl b/cmd/crossplane/docs-templates/command-reference.md.tmpl new file mode 100644 index 0000000..b1ff98c --- /dev/null +++ b/cmd/crossplane/docs-templates/command-reference.md.tmpl @@ -0,0 +1,45 @@ +--- +weight: 50 +title: Command Reference +description: "Command reference for the Crossplane CLI" +--- + + + +This documentation is for the `crossplane` CLI [[ .Version ]]. + +[[ range .Commands ]] + + +[[ .Heading ]] [[ .FullPath ]] + + + +[[ if .Help ]][[ .Help ]][[ end ]] + +[[ if .Detail ]][[ .Detail ]][[ end ]] + +[[ .SubHeading ]] Usage + +``` +crossplane [[ .Summary ]] +``` +[[- if .Positional ]] +[[ .SubHeading ]] Arguments + +{{< table "table table-sm table-striped" >}} +| Argument | Description | +|----------|-------------| +[[ range .Positional ]]| `[[ .Display ]]` | [[ if not .Required ]]*(optional)* [[ end ]][[ .Help ]] | +[[ end ]]{{< /table >}} +[[ end ]] +[[- if .Flags ]] +[[ .SubHeading ]] Flags + +{{< table "table table-sm table-striped" >}} +| Short flag | Long flag | Description | +|------------|-----------|-------------| +[[ range .Flags ]]| [[ if .Short ]]`[[ .Short ]]`[[ end ]] | `[[ .Long ]]` | [[ if .Required ]]**Required.** [[ end ]][[ .Help ]] | +[[ end ]]{{< /table >}} +[[ end ]] +[[ end ]] diff --git a/cmd/crossplane/docs.go b/cmd/crossplane/docs.go new file mode 100644 index 0000000..2ab4591 --- /dev/null +++ b/cmd/crossplane/docs.go @@ -0,0 +1,257 @@ +/* +Copyright 2026 The Crossplane 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 main + +import ( + "bytes" + "fmt" + "os" + "regexp" + "slices" + "strings" + "text/template" + + "github.com/alecthomas/kong" + + "github.com/crossplane/crossplane-runtime/v2/pkg/version" + + _ "embed" +) + +//go:embed docs-templates/command-reference.md.tmpl +var docsTmpl string + +type docsCmd struct { + OutputFile string `default:"command-reference.md" help:"Path to write the generated command-reference markdown file." name:"output-file" short:"o" type:"path"` + + tmpl *template.Template +} + +// AfterApply prepares the template for execution. +func (d *docsCmd) AfterApply() error { + // Use [[ ]] as the action delimiters so the template can contain Hugo + // shortcodes like {{< table >}} without conflict. + t, err := template.New("docs").Delims("[[", "]]").Parse(docsTmpl) + if err != nil { + return err + } + d.tmpl = t + return nil +} + +// docsPositional describes a positional argument in the generated docs. +type docsPositional struct { + Display string + Help string + Required bool +} + +// docsFlag describes a flag in the generated docs. +type docsFlag struct { + Long string + Short string + Help string + Required bool +} + +// docsCommand is the per-command template input. +type docsCommand struct { + FullPath string + Heading string + SubHeading string + Help string + Detail string + Summary string + Positional []docsPositional + Flags []docsFlag +} + +// docsInput is the top-level template input. +type docsInput struct { + Version string + Commands []docsCommand +} + +// Run walks the kong model and writes the generated docs file. +func (d *docsCmd) Run(ctx *kong.Context) error { + root := ctx.Model.Node + + ver := version.New().GetVersionString() + if ver == "" { + ver = "(development build)" + } + input := docsInput{ + Version: ver, + } + + if err := traverseChildren(root, func(n *kong.Node) error { + input.Commands = append(input.Commands, buildDocsCommand(n)) + return nil + }); err != nil { + return err + } + + slices.SortFunc(input.Commands, func(a, b docsCommand) int { + return strings.Compare(a.FullPath, b.FullPath) + }) + + var buf bytes.Buffer + if err := d.tmpl.Execute(&buf, input); err != nil { + return err + } + return os.WriteFile(d.OutputFile, buf.Bytes(), 0o644) //nolint:gosec // 0644 is a fine mode for docs. +} + +func buildDocsCommand(n *kong.Node) docsCommand { + headingLevel := min(depth(n)+1, 6) + dc := docsCommand{ + FullPath: n.FullPath(), + Heading: strings.Repeat("#", headingLevel), + SubHeading: strings.Repeat("#", min(headingLevel+1, 6)), + Help: n.Help, + Detail: normalizeDetail(n.Detail, headingLevel), + Summary: n.Summary(), + } + for _, p := range n.Positional { + dc.Positional = append(dc.Positional, docsPositional{ + Display: p.Summary(), + Help: p.Help, + Required: p.Required, + }) + } + for _, f := range n.Flags { + if f.Hidden { + continue + } + df := docsFlag{ + Long: "--" + f.Name, + Help: f.Help, + Required: f.Required, + } + if f.Short != 0 { + df.Short = "-" + string(f.Short) + } + // Append the placeholder for non-bool, non-counter flags so the docs + // look like the CLI help. + if !f.IsBool() && !f.IsCounter() { + df.Long = fmt.Sprintf("--%s=%s", f.Name, f.FormatPlaceHolder()) + } + dc.Flags = append(dc.Flags, df) + } + return dc +} + +// normalizeDetail prepares embedded help markdown for inclusion in the +// generated Hugo docs page by: +// +// 1. Demoting headings as needed so the content nests below the command's +// heading at headingLevel. +// 2. Replacing any special blockquotes with pretty hugo ones. +// 3. Adding pretty hugo table annotations to tables. +func normalizeDetail(detail string, headingLevel int) string { + detail = strings.TrimSpace(detail) + if headingLevel == 0 { + return detail + } + + // We'll demote each heading so that it's at least headingLevel+1 + // deep. I.e., nesting an H1 under an H1 results in an H2. + demote := headingLevel - 1 + lines := strings.SplitSeq(detail, "\n") + + var ( + sb strings.Builder + codeBlock = false + bq = false + table = false + ) + for line := range lines { + // Skip any lines in a code block (```). + if strings.HasPrefix(line, "```") { + codeBlock = !codeBlock + sb.WriteString(line + "\n") + continue + } + if codeBlock { + sb.WriteString(line + "\n") + continue + } + + // Demote headings, capping at H6. + if strings.HasPrefix(line, "#") { + line = strings.Repeat("#", demote) + line + } + + // Convert special blockquotes into pretty Hugo blocks. + bqRE := regexp.MustCompile(`^> \*\*(\w+):\*\* `) + bqMatch := bqRE.FindStringSubmatch(line) + if bqMatch != nil { + bq = true + fmt.Fprintf(&sb, "{{}}\n", strings.ToLower(bqMatch[1])) + line = strings.TrimPrefix(line, bqMatch[0]) + sb.WriteString(line + "\n") + continue + } + if bq { + if !strings.HasPrefix(line, ">") { + sb.WriteString("{{< /hint >}}\n") + bq = false + } + line = strings.TrimSpace(strings.TrimPrefix(line, ">")) + } + + // Add pretty table markers to tables. + if strings.HasPrefix(line, "|") && !table { + table = true + sb.WriteString("{{}}\n") + } + if table && !strings.HasPrefix(line, "|") { + sb.WriteString("{{< /table >}}\n") + table = false + } + + sb.WriteString(line + "\n") + } + + return strings.TrimSpace(sb.String()) +} + +func depth(n *kong.Node) int { + d := 0 + for cur := n.Parent; cur != nil; cur = cur.Parent { + d++ + } + return d +} + +// traverseChildren walks the kong tree calling fn on each non-hidden node. +func traverseChildren(root *kong.Node, fn func(*kong.Node) error) error { + root.Aliases = nil + + if root.Hidden { + return nil + } + if err := fn(root); err != nil { + return err + } + for _, node := range root.Children { + if err := traverseChildren(node, fn); err != nil { + return err + } + } + return nil +} diff --git a/cmd/crossplane/help.go b/cmd/crossplane/help.go new file mode 100644 index 0000000..65a4db9 --- /dev/null +++ b/cmd/crossplane/help.go @@ -0,0 +1,393 @@ +/* +Copyright 2026 The Crossplane 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 main + +import ( + "bytes" + "fmt" + "go/doc" + "io" + "os" + "strings" + + "github.com/alecthomas/kong" + "github.com/charmbracelet/x/term" + + "github.com/crossplane/cli/v2/internal/style" +) + +// helpPrinter is our custom help printer for kong. It works much like the +// upstream kong help printer except we format detailed help using markdown. We +// have also removed options we don't use to simplify the code. +func helpPrinter(options kong.HelpOptions, ctx *kong.Context) error { + if ctx.Empty() { + options.Summary = false + } + w := newHelpWriter(ctx, options) + selected := ctx.Selected() + if selected == nil { + printApp(w, ctx.Model) + } else { + printCommand(w, ctx.Model, selected) + } + return w.Write(ctx.Stdout) +} + +func printApp(w *helpWriter, app *kong.Application) { + if !w.NoAppSummary { + w.Printf("Usage: %s%s", app.Name, app.Summary()) + } + printNodeDetail(w, app.Node) + cmds := app.Leaves(true) + if len(cmds) > 0 && app.HelpFlag != nil { + w.Print("") + if w.Summary { + w.Printf(`Run "%s --help" for more information.`, app.Name) + } else { + w.Printf(`Run "%s --help" for more information on a command.`, app.Name) + } + } +} + +func printCommand(w *helpWriter, app *kong.Application, cmd *kong.Command) { + if !w.NoAppSummary { + w.Printf("Usage: %s %s", app.Name, cmd.Summary()) + } + printNodeDetail(w, cmd) + if w.Summary && app.HelpFlag != nil { + w.Print("") + w.Printf(`Run "%s --help" for more information.`, cmd.FullPath()) + } +} + +func printNodeDetail(w *helpWriter, node *kong.Node) { + if node.Help != "" { + w.Print("") + w.Wrap(node.Help) + } + if w.Summary { + return + } + // Upstream kong formats detailed help with the go/doc package. We use + // markdown via the glamour library. + if node.Detail != "" { + w.Print(style.RenderMarkdown(node.Detail)) + } + if len(node.Positional) > 0 { + w.Print("Arguments:") + writePositionals(w.Indent(), node.Positional) + } + printFlags := func() { + if flags := node.AllFlags(true); len(flags) > 0 { + groupedFlags := collectFlagGroups(flags) + for _, group := range groupedFlags { + if group.Metadata.Title != "" { + w.Print("") + w.Wrap(group.Metadata.Title) + } + if group.Metadata.Description != "" { + w.Indent().Wrap(group.Metadata.Description) + w.Print("") + } + writeFlags(w.Indent(), group.Flags) + } + } + } + if !w.FlagsLast { + printFlags() + } + + cmds := node.Children + if len(cmds) > 0 { + iw := w.Indent() + groupedCmds := collectCommandGroups(cmds) + for _, group := range groupedCmds { + if group.Metadata.Title != "" { + w.Print("") + w.Wrap(group.Metadata.Title) + } + if group.Metadata.Description != "" { + w.Indent().Wrap(group.Metadata.Description) + w.Print("") + } + + writeCompactCommandList(group.Commands, iw) + } + } + if w.FlagsLast { + printFlags() + } +} + +func writeCompactCommandList(cmds []*kong.Node, iw *helpWriter) { + rows := [][2]string{} + for _, cmd := range cmds { + if cmd.Hidden { + continue + } + rows = append(rows, [2]string{cmd.Path(), cmd.Help}) + } + writeTwoColumns(iw, rows) +} + +type helpFlagGroup struct { + Metadata *kong.Group + Flags [][]*kong.Flag +} + +func collectFlagGroups(flags [][]*kong.Flag) []helpFlagGroup { + // Group keys in order of appearance. + groups := []*kong.Group{} + // Flags grouped by their group key. + flagsByGroup := map[string][][]*kong.Flag{} + + for _, levelFlags := range flags { + levelFlagsByGroup := map[string][]*kong.Flag{} + + for _, flag := range levelFlags { + key := "" + if flag.Group != nil { + key = flag.Group.Key + groupAlreadySeen := false + for _, group := range groups { + if key == group.Key { + groupAlreadySeen = true + break + } + } + if !groupAlreadySeen { + groups = append(groups, flag.Group) + } + } + + levelFlagsByGroup[key] = append(levelFlagsByGroup[key], flag) + } + + for key, flags := range levelFlagsByGroup { + flagsByGroup[key] = append(flagsByGroup[key], flags) + } + } + + out := []helpFlagGroup{} + // Ungrouped flags are always displayed first. + if ungroupedFlags, ok := flagsByGroup[""]; ok { + out = append(out, helpFlagGroup{ + Metadata: &kong.Group{Title: "Flags:"}, + Flags: ungroupedFlags, + }) + } + for _, group := range groups { + out = append(out, helpFlagGroup{Metadata: group, Flags: flagsByGroup[group.Key]}) + } + return out +} + +type helpCommandGroup struct { + Metadata *kong.Group + Commands []*kong.Node +} + +func collectCommandGroups(nodes []*kong.Node) []helpCommandGroup { + // Groups in order of appearance. + groups := []*kong.Group{} + // Nodes grouped by their group key. + nodesByGroup := map[string][]*kong.Node{} + + for _, node := range nodes { + key := "" + if group := node.ClosestGroup(); group != nil { + key = group.Key + if _, ok := nodesByGroup[key]; !ok { + groups = append(groups, group) + } + } + nodesByGroup[key] = append(nodesByGroup[key], node) + } + + out := []helpCommandGroup{} + // Ungrouped nodes are always displayed first. + if ungroupedNodes, ok := nodesByGroup[""]; ok { + out = append(out, helpCommandGroup{ + Metadata: &kong.Group{Title: "Commands:"}, + Commands: ungroupedNodes, + }) + } + for _, group := range groups { + out = append(out, helpCommandGroup{Metadata: group, Commands: nodesByGroup[group.Key]}) + } + return out +} + +type helpWriter struct { + kong.HelpOptions + + indent string + width int + lines *[]string + helpFormatter kong.HelpValueFormatter +} + +func newHelpWriter(_ *kong.Context, options kong.HelpOptions) *helpWriter { + // Don't use kong's insane width guessing algorithm. Just get the term size + // and cap at 120 to make paragraphs nice to read. + wrapWidth, _, _ := term.GetSize(os.Stdout.Fd()) + wrapWidth = min(wrapWidth, 120) + + lines := []string{} + if options.WrapUpperBound > 0 && wrapWidth > options.WrapUpperBound { + wrapWidth = options.WrapUpperBound + } + w := &helpWriter{ + indent: "", + width: wrapWidth, + lines: &lines, + helpFormatter: kong.DefaultHelpValueFormatter, + HelpOptions: options, + } + return w +} + +func (h *helpWriter) Printf(format string, args ...any) { + h.Print(fmt.Sprintf(format, args...)) +} + +func (h *helpWriter) Print(text string) { + *h.lines = append(*h.lines, strings.TrimRight(h.indent+text, " ")) +} + +// Indent returns a new helpWriter indented by two characters. +func (h *helpWriter) Indent() *helpWriter { + return &helpWriter{indent: h.indent + " ", lines: h.lines, width: h.width - 2, HelpOptions: h.HelpOptions, helpFormatter: h.helpFormatter} +} + +func (h *helpWriter) String() string { + return strings.Join(*h.lines, "\n") +} + +func (h *helpWriter) Write(w io.Writer) error { + for _, line := range *h.lines { + _, err := io.WriteString(w, line+"\n") + if err != nil { + return err + } + } + return nil +} + +func (h *helpWriter) Wrap(text string) { + w := bytes.NewBuffer(nil) + doc.ToText(w, strings.TrimSpace(text), "", " ", h.width) //nolint:staticcheck // cross-package links not possible + for line := range strings.SplitSeq(strings.TrimSpace(w.String()), "\n") { + h.Print(line) + } +} + +func writePositionals(w *helpWriter, args []*kong.Positional) { + rows := make([][2]string, 0, len(args)) + for _, arg := range args { + rows = append(rows, [2]string{arg.Summary(), w.helpFormatter(arg)}) + } + writeTwoColumns(w, rows) +} + +func writeFlags(w *helpWriter, groups [][]*kong.Flag) { + rows := [][2]string{} + haveShort := false + for _, group := range groups { + for _, flag := range group { + if flag.Short != 0 { + haveShort = true + break + } + } + } + for i, group := range groups { + if i > 0 { + rows = append(rows, [2]string{"", ""}) + } + for _, flag := range group { + if !flag.Hidden { + rows = append(rows, [2]string{formatFlag(haveShort, flag), w.helpFormatter(flag.Value)}) + } + } + } + writeTwoColumns(w, rows) +} + +const ( + defaultIndent = 2 + defaultColumnPadding = 4 +) + +func writeTwoColumns(w *helpWriter, rows [][2]string) { + maxLeft := max(375*w.width/1000, 30) + // Find size of first column. + leftSize := 0 + for _, row := range rows { + if c := len(row[0]); c > leftSize && c < maxLeft { + leftSize = c + } + } + + offsetStr := strings.Repeat(" ", leftSize+defaultColumnPadding) + + for _, row := range rows { + buf := bytes.NewBuffer(nil) + doc.ToText(buf, row[1], "", strings.Repeat(" ", defaultIndent), w.width-leftSize-defaultColumnPadding) //nolint:staticcheck // cross-package links not possible + lines := strings.Split(strings.TrimRight(buf.String(), "\n"), "\n") + + line := fmt.Sprintf("%-*s", leftSize, row[0]) + if len(row[0]) < maxLeft { + line += fmt.Sprintf("%*s%s", defaultColumnPadding, "", lines[0]) + lines = lines[1:] + } + w.Print(line) + for _, line := range lines { + w.Printf("%s%s", offsetStr, line) + } + } +} + +const negatableDefault = "_" + +// haveShort will be true if there are short flags present at all in the help. Useful for column alignment. +func formatFlag(haveShort bool, flag *kong.Flag) string { + flagString := "" + name := flag.Name + isBool := flag.IsBool() + isCounter := flag.IsCounter() + + short := "" + if flag.Short != 0 { + short = "-" + string(flag.Short) + ", " + } else if haveShort { + short = " " + } + + if isBool && flag.Tag.Negatable == negatableDefault { + name = "[no-]" + name + } else if isBool && flag.Tag.Negatable != "" { + name += "/" + flag.Tag.Negatable + } + + flagString += fmt.Sprintf("%s--%s", short, name) + + if !isBool && !isCounter { + flagString += fmt.Sprintf("=%s", flag.FormatPlaceHolder()) + } + return flagString +} diff --git a/cmd/crossplane/help.md b/cmd/crossplane/help.md new file mode 100644 index 0000000..a74f031 --- /dev/null +++ b/cmd/crossplane/help.md @@ -0,0 +1,3 @@ +A command line tool for interacting with Crossplane. + +Please report issues and feature requests at https://github.com/crossplane/cli. diff --git a/cmd/crossplane/main.go b/cmd/crossplane/main.go index ae8d2d6..9a19a2e 100644 --- a/cmd/crossplane/main.go +++ b/cmd/crossplane/main.go @@ -41,8 +41,13 @@ import ( "github.com/crossplane/cli/v2/cmd/crossplane/xpkg" "github.com/crossplane/cli/v2/internal/config" "github.com/crossplane/cli/v2/internal/maturity" + + _ "embed" ) +//go:embed help.md +var helpDescription string + var _ = kong.Must(&cli{}) type ( @@ -73,6 +78,9 @@ type cli struct { // Hidden top-level alias for render, since it's GA but has moved. Render renderxr.Cmd `cmd:"" help:"Render Crossplane compositions locally using functions." hidden:""` + // Hidden command to generate the command-reference docs page. + GenerateDocs docsCmd `cmd:"" help:"Generate command-reference docs in markdown format." hidden:""` + // Flags. ConfigPath string `env:"CROSSPLANE_CONFIG" help:"Path to the crossplane CLI config file." name:"config" placeholder:"PATH"` Verbose verboseFlag `help:"Print verbose logging statements." name:"verbose"` @@ -102,19 +110,17 @@ func main() { parser := kong.Must(&cli{}, kong.Name("crossplane"), - kong.Description("A command line tool for interacting with Crossplane."), // Binding a variable to kong context makes it available to all commands // at runtime. kong.BindTo(logger, (*logging.Logger)(nil)), kong.BindTo(configcmd.ConfigPath(cfgPath), (*configcmd.ConfigPath)(nil)), - kong.ConfigureHelp(kong.HelpOptions{ - FlagsLast: true, - Compact: true, - WrapUpperBound: 80, - NoExpandSubcommands: true, - }), + kong.Help(helpPrinter), kong.UsageOnError()) + // Set the top-level Detail to the embedded markdown so it renders via the + // markdown help printer. Done before maturity.Apply, which appends to it. + parser.Model.Detail = helpDescription + kongplete.Complete(parser, kongplete.WithPredictors(completion.Predictors()), ) diff --git a/cmd/crossplane/render/op/cmd.go b/cmd/crossplane/render/op/cmd.go index 6abc564..7780a8f 100644 --- a/cmd/crossplane/render/op/cmd.go +++ b/cmd/crossplane/render/op/cmd.go @@ -36,8 +36,13 @@ import ( "github.com/crossplane/cli/v2/cmd/crossplane/render" "github.com/crossplane/cli/v2/cmd/crossplane/render/contextfn" + + _ "embed" ) +//go:embed help/render.md +var helpDetail string + // Cmd arguments and flags for alpha render op subcommand. type Cmd struct { render.EngineFlags `prefix:""` @@ -68,94 +73,7 @@ type Cmd struct { // Help prints out the help for the alpha render op command. func (c *Cmd) Help() string { - return ` -This command shows you what resources an Operation would create or mutate by -printing them to stdout. It runs the Crossplane render engine to produce -high-fidelity output that matches what the real reconciler would produce. - -For Operations, it runs the operation function pipeline and shows what -resources the operation would mutate. - -Functions are pulled and run using Docker by default. You can add -the following annotations to each function to change how they're run: - - render.crossplane.io/runtime: "Development" - - Connect to a function that is already running, instead of using Docker. This - is useful to develop and debug new functions. The function must be listening - at localhost:9443 and running with the --insecure flag. - - render.crossplane.io/runtime-development-target: "dns:///example.org:7443" - - Connect to a function running somewhere other than localhost:9443. The - target uses gRPC target syntax. - - render.crossplane.io/runtime-docker-cleanup: "Orphan" - - Don't stop the function's Docker container after rendering. - - render.crossplane.io/runtime-docker-name: "" - - create a container with that name and also reuse it as long as it is running or can be restarted. - - render.crossplane.io/runtime-docker-pull-policy: "Always" - - Always pull the function's package, even if it already exists locally. - Other supported values are Never, or IfNotPresent. - -Use the standard DOCKER_HOST, DOCKER_API_VERSION, DOCKER_CERT_PATH, and -DOCKER_TLS_VERIFY environment variables to configure how this command connects -to the Docker daemon. - -Examples: - - # Render an Operation. - crossplane operation render operation.yaml functions.yaml - - # Pin the Crossplane version used for rendering. - crossplane operation render operation.yaml functions.yaml \ - --crossplane-version=v2.2.1 - - # Use a local crossplane binary instead of Docker. - crossplane operation render operation.yaml functions.yaml \ - --crossplane-binary=/usr/local/bin/crossplane - - # Pass context values to the function pipeline. - crossplane operation render operation.yaml functions.yaml \ - --context-values=apiextensions.crossplane.io/environment='{"key": "value"}' - - # Pass required resources functions can request. - crossplane operation render operation.yaml functions.yaml \ - --required-resources=required-resources.yaml - - # Pass OpenAPI schemas for functions that need them. - crossplane operation render operation.yaml functions.yaml \ - --required-schemas=schemas/ - - # Render a WatchOperation with a watched resource. - crossplane operation render watchoperation.yaml functions.yaml \ - --watched-resource=watched-configmap.yaml - - # Pass credentials to functions that need them. - crossplane operation render operation.yaml functions.yaml \ - --function-credentials=credentials.yaml - - # Include function results and context in output. - crossplane operation render operation.yaml functions.yaml -r -c - - # Include the full Operation with original spec and metadata. - crossplane operation render operation.yaml functions.yaml -o - - # Override function annotations for remote Docker daemon. - crossplane operation render operation.yaml functions.yaml \ - -a render.crossplane.io/runtime-docker-publish-address=0.0.0.0 \ - -a render.crossplane.io/runtime-docker-target=192.168.1.100 - - # Use development runtime with custom target. - crossplane operation render operation.yaml functions.yaml \ - -a render.crossplane.io/runtime=Development \ - -a render.crossplane.io/runtime-development-target=localhost:9444 -` + return helpDetail } // AfterApply implements kong.AfterApply. diff --git a/cmd/crossplane/render/op/help/render.md b/cmd/crossplane/render/op/help/render.md new file mode 100644 index 0000000..23a37dc --- /dev/null +++ b/cmd/crossplane/render/op/help/render.md @@ -0,0 +1,116 @@ +The `operation render` command shows you what resources an Operation would +create or mutate by running the operation locally and printing its results. It +runs the Crossplane render engine (either in a Docker container or via a local +binary) to produce high-fidelity output that matches what the real reconciler +would produce. + +> **Important:** This command runs operation functions and the Crossplane render +> engine using Docker by default, requiring a working Docker installation. See +> the function annotations and `--crossplane-binary` option below to understand +> how to render without Docker. + +## Function runtime configuration + +Operation Functions are pulled and run using Docker by default. You can add the +following annotations to each Function to change how they're run: + +| Annotation | Purpose | +| ---------- | ------- | +| `render.crossplane.io/runtime: "Development"` | Connect to a Function that is already running, instead of using Docker. This is useful to develop and debug new Functions. The Function must be listening at `localhost:9443` and running with the `--insecure` flag. | +| `render.crossplane.io/runtime-development-target: "dns:///example.org:7443"` | Connect to a Function running somewhere other than `localhost:9443`. The target uses gRPC target syntax (e.g., `dns:///example.org:7443` or simply `example.org:7443`). | +| `render.crossplane.io/runtime-docker-cleanup: "Orphan"` | Don't stop the Function's Docker container after rendering. | +| `render.crossplane.io/runtime-docker-name: ""` | Create a container with that name and reuse it as long as it is running or can be restarted. | +| `render.crossplane.io/runtime-docker-pull-policy: "Always"` | Always pull the Function's package, even if it already exists locally. Other supported values are `Never` or `IfNotPresent`. | +| `render.crossplane.io/runtime-docker-publish-address: "0.0.0.0"` | Host address that Docker should publish the Function's container port to. Defaults to `127.0.0.1` (localhost only). Use `0.0.0.0` to publish to all host network interfaces, enabling access from remote machines. | +| `render.crossplane.io/runtime-docker-target: "docker-host"` | Address that the render CLI should use to connect to the Function's Docker container. If not specified, uses the publish address. | + +Use the standard `DOCKER_HOST`, `DOCKER_API_VERSION`, `DOCKER_CERT_PATH`, and +`DOCKER_TLS_VERIFY` environment variables to configure how this command connects +to the Docker daemon. See the [Docker environment +variables](https://docs.docker.com/engine/reference/commandline/cli/#environment-variables) +reference. + +## Examples + +Render an Operation: + +```shell +crossplane operation render operation.yaml functions.yaml +``` + +Pin the Crossplane version used for rendering: + +```shell +crossplane operation render operation.yaml functions.yaml \ + --crossplane-version=v2.2.1 +``` + +Use a local crossplane binary instead of Docker: + +```shell +crossplane operation render operation.yaml functions.yaml \ + --crossplane-binary=/usr/local/bin/crossplane +``` + +Pass context values to the function pipeline: + +```shell +crossplane operation render operation.yaml functions.yaml \ + --context-values=apiextensions.crossplane.io/environment='{"key": "value"}' +``` + +Pass required resources functions can request: + +```shell +crossplane operation render operation.yaml functions.yaml \ + --required-resources=required-resources.yaml +``` + +Pass OpenAPI schemas for functions that need them: + +```shell +crossplane operation render operation.yaml functions.yaml \ + --required-schemas=schemas/ +``` + +Render a WatchOperation with a watched resource: + +```shell +crossplane operation render watchoperation.yaml functions.yaml \ + --watched-resource=watched-configmap.yaml +``` + +Pass credentials to functions that need them: + +```shell +crossplane operation render operation.yaml functions.yaml \ + --function-credentials=credentials.yaml +``` + +Include function results and context in output: + +```shell +crossplane operation render operation.yaml functions.yaml -r -c +``` + +Include the full Operation with original spec and metadata: + +```shell +crossplane operation render operation.yaml functions.yaml -o +``` + +Override function annotations for remote Docker daemon: + +```shell +crossplane operation render operation.yaml functions.yaml \ + -a render.crossplane.io/runtime-docker-publish-address=0.0.0.0 \ + -a render.crossplane.io/runtime-docker-target=192.168.1.100 +``` + +Use development runtime with custom target for all functions: + +```shell +crossplane operation render operation.yaml functions.yaml \ + -a render.crossplane.io/runtime=Development \ + -a render.crossplane.io/runtime-development-target=localhost:9444 +``` diff --git a/cmd/crossplane/render/xr/cmd.go b/cmd/crossplane/render/xr/cmd.go index 90abee6..876261e 100644 --- a/cmd/crossplane/render/xr/cmd.go +++ b/cmd/crossplane/render/xr/cmd.go @@ -39,8 +39,13 @@ import ( "github.com/crossplane/cli/v2/cmd/crossplane/render" "github.com/crossplane/cli/v2/cmd/crossplane/render/contextfn" + + _ "embed" ) +//go:embed help/render.md +var helpDetail string + // Cmd arguments and flags for the `render xr` subcommand. type Cmd struct { render.EngineFlags `prefix:""` @@ -74,98 +79,7 @@ type Cmd struct { // Help prints out the help for the render command. func (c *Cmd) Help() string { - return ` -This command shows you what composed resources Crossplane would create by -printing them to stdout. It also prints any changes that would be made to the -status of the XR. It runs the Crossplane render engine (either in a Docker -container or via a local binary) to produce high-fidelity output that matches -what the real reconciler would produce. - -Composition Functions are pulled and run using Docker by default. You can add -the following annotations to each Function to change how they're run: - - render.crossplane.io/runtime: "Development" - - Connect to a Function that is already running, instead of using Docker. This - is useful to develop and debug new Functions. The Function must be listening - at localhost:9443 and running with the --insecure flag. - - render.crossplane.io/runtime-development-target: "dns:///example.org:7443" - - Connect to a Function running somewhere other than localhost:9443. The - target uses gRPC target syntax (e.g., dns:///example.org:7443 or simply example.org:7443). - - render.crossplane.io/runtime-docker-cleanup: "Orphan" - - Don't stop the Function's Docker container after rendering. - - render.crossplane.io/runtime-docker-name: "" - - create a container with that name and also reuse it as long as it is running or can be restarted. - - render.crossplane.io/runtime-docker-pull-policy: "Always" - - Always pull the Function's package, even if it already exists locally. - Other supported values are Never, or IfNotPresent. - - render.crossplane.io/runtime-docker-publish-address: "0.0.0.0" - - Host address that Docker should publish the Function's container port to. - Defaults to 127.0.0.1 (localhost only). Use 0.0.0.0 to publish to all host - network interfaces, enabling access from remote machines. - - render.crossplane.io/runtime-docker-target: "docker-host" - - Address that the render CLI should use to connect to the Function's Docker - container. If not specified, uses the publish address. - -Use the standard DOCKER_HOST, DOCKER_API_VERSION, DOCKER_CERT_PATH, and -DOCKER_TLS_VERIFY environment variables to configure how this command connects -to the Docker daemon. - -Examples: - - # Simulate creating a new XR. - crossplane composition render xr.yaml composition.yaml functions.yaml - - # Simulate updating an XR that already exists. - crossplane composition render xr.yaml composition.yaml functions.yaml \ - --observed-resources=existing-observed-resources.yaml - - # Pin the Crossplane version used for rendering. - crossplane composition render xr.yaml composition.yaml functions.yaml \ - --crossplane-version=v2.3.0 - - # Use a local crossplane binary instead of Docker. - crossplane composition render xr.yaml composition.yaml functions.yaml \ - --crossplane-binary=/usr/local/bin/crossplane - - # Pass context values to the Function pipeline. - crossplane composition render xr.yaml composition.yaml functions.yaml \ - --context-values=apiextensions.crossplane.io/environment='{"key": "value"}' - - # Pass required resources Functions in the pipeline can request. - crossplane composition render xr.yaml composition.yaml functions.yaml \ - --required-resources=required-resources.yaml - - # Pass OpenAPI schemas for Functions that need them. - crossplane composition render xr.yaml composition.yaml functions.yaml \ - --required-schemas=schemas/ - - # Pass credentials to Functions in the pipeline that need them. - crossplane composition render xr.yaml composition.yaml functions.yaml \ - --function-credentials=credentials.yaml - - # Override function annotations for a remote Docker daemon. - DOCKER_HOST=tcp://192.168.1.100:2376 crossplane composition render xr.yaml composition.yaml functions.yaml \ - -a render.crossplane.io/runtime-docker-publish-address=0.0.0.0 \ - -a render.crossplane.io/runtime-docker-target=192.168.1.100 - - # Force all functions to use development runtime. - crossplane composition render xr.yaml composition.yaml functions.yaml \ - -a render.crossplane.io/runtime=Development \ - -a render.crossplane.io/runtime-development-target=localhost:9444 -` + return helpDetail } // AfterApply implements kong.AfterApply. diff --git a/cmd/crossplane/render/xr/help/render.md b/cmd/crossplane/render/xr/help/render.md new file mode 100644 index 0000000..ab0ed95 --- /dev/null +++ b/cmd/crossplane/render/xr/help/render.md @@ -0,0 +1,151 @@ +The `composition render` command shows you what resources a Composition would +create or mutate by running the composition locally and printing its results. It +also prints any changes that would be made to the status of the XR. It runs the +Crossplane render engine (either in a Docker container or via a local binary) to +produce high-fidelity output that matches what the real reconciler would +produce. + +By default, only the `status` field and `metadata.name` of the XR are +printed. Use `--include-full-xr` (`-x`) to include the full XR `spec` and +`metadata`. + +> **Important:** This command runs composition functions and the Crossplane +> render engine using Docker by default, requiring a working Docker +> installation. See the function annotations and `--crossplane-binary` option +> below to understand how to render without Docker. + +## Function runtime configuration + +Composition Functions are pulled and run using Docker by default. You can add +the following annotations to each Function to change how they're run: + +| Annotation | Purpose | +| ---------- | ------- | +| `render.crossplane.io/runtime: "Development"` | Connect to a Function that is already running, instead of using Docker. This is useful to develop and debug new Functions. The Function must be listening at `localhost:9443` and running with the `--insecure` flag. | +| `render.crossplane.io/runtime-development-target: "dns:///example.org:7443"` | Connect to a Function running somewhere other than `localhost:9443`. The target uses gRPC target syntax (e.g., `dns:///example.org:7443` or simply `example.org:7443`). | +| `render.crossplane.io/runtime-docker-cleanup: "Orphan"` | Don't stop the Function's Docker container after rendering. | +| `render.crossplane.io/runtime-docker-name: ""` | Create a container with that name and reuse it as long as it is running or can be restarted. | +| `render.crossplane.io/runtime-docker-pull-policy: "Always"` | Always pull the Function's package, even if it already exists locally. Other supported values are `Never` or `IfNotPresent`. | +| `render.crossplane.io/runtime-docker-publish-address: "0.0.0.0"` | Host address that Docker should publish the Function's container port to. Defaults to `127.0.0.1` (localhost only). Use `0.0.0.0` to publish to all host network interfaces, enabling access from remote machines. | +| `render.crossplane.io/runtime-docker-target: "docker-host"` | Address that the render CLI should use to connect to the Function's Docker container. If not specified, uses the publish address. | + +Use the standard `DOCKER_HOST`, `DOCKER_API_VERSION`, `DOCKER_CERT_PATH`, and +`DOCKER_TLS_VERIFY` environment variables to configure how this command connects +to the Docker daemon. See the [Docker environment +variables](https://docs.docker.com/engine/reference/commandline/cli/#environment-variables) +reference. + +## Function context + +The `--context-files` and `--context-values` flags pass data to each Function's +`context`. The context is JSON-formatted data. + +## Function results + +If a Function emits events with statuses, use `--include-function-results` +(`-r`) to print them alongside the rendered resources. + +## Observed (mock) resources + +`--observed-resources` (`-o`) lets you pass mocked managed resources to the +Function pipeline. `render` treats those inputs as if they were resources +observed in a Crossplane cluster, so Functions can reference and manipulate +them. + +The argument may be a single YAML file containing multiple resources or a +directory of YAML files. The schema of the mocked resources isn't validated and +may contain any data. + +```yaml +apiVersion: example.org/v1alpha1 +kind: ComposedResource +metadata: + name: test-render-b + annotations: + crossplane.io/composition-resource-name: resource-b +spec: + coolerField: "I'm cooler!" +``` + +## Required (extra) resources + +Required resources let a Composition request Crossplane objects on the cluster +that aren't part of the Composition. Pass them with `--required-resources` +(`-e`) — a YAML file or directory of YAML files of resources to mock. Use this +with a Function like +[function-extra-resources](https://github.com/crossplane-contrib/function-extra-resources) +or the built-in support in +[function-go-templating](https://github.com/crossplane-contrib/function-go-templating?tab=readme-ov-file#extraresources). + +## Examples + +Simulate creating a new XR: + +```shell +crossplane composition render xr.yaml composition.yaml functions.yaml +``` + +Simulate updating an XR that already exists: + +```shell +crossplane composition render xr.yaml composition.yaml functions.yaml \ + --observed-resources=existing-observed-resources.yaml +``` + +Pin the Crossplane version used for rendering: + +```shell +crossplane composition render xr.yaml composition.yaml functions.yaml \ + --crossplane-version=v2.3.0 +``` + +Use a local crossplane binary instead of Docker: + +```shell +crossplane composition render xr.yaml composition.yaml functions.yaml \ + --crossplane-binary=/usr/local/bin/crossplane +``` + +Pass context values to the Function pipeline: + +```shell +crossplane composition render xr.yaml composition.yaml functions.yaml \ + --context-values=apiextensions.crossplane.io/environment='{"key": "value"}' +``` + +Pass required resources Functions in the pipeline can request: + +```shell +crossplane composition render xr.yaml composition.yaml functions.yaml \ + --required-resources=required-resources.yaml +``` + +Pass OpenAPI schemas for Functions that need them: + +```shell +crossplane composition render xr.yaml composition.yaml functions.yaml \ + --required-schemas=schemas/ +``` + +Pass credentials to Functions in the pipeline that need them: + +```shell +crossplane composition render xr.yaml composition.yaml functions.yaml \ + --function-credentials=credentials.yaml +``` + +Override function annotations for a remote Docker daemon: + +```shell +DOCKER_HOST=tcp://192.168.1.100:2376 crossplane composition render xr.yaml composition.yaml functions.yaml \ + -a render.crossplane.io/runtime-docker-publish-address=0.0.0.0 \ + -a render.crossplane.io/runtime-docker-target=192.168.1.100 +``` + +Force all functions to use development runtime: + +```shell +crossplane composition render xr.yaml composition.yaml functions.yaml \ + -a render.crossplane.io/runtime=Development \ + -a render.crossplane.io/runtime-development-target=localhost:9444 +``` diff --git a/cmd/crossplane/top/help/top.md b/cmd/crossplane/top/help/top.md new file mode 100644 index 0000000..cfcb2fd --- /dev/null +++ b/cmd/crossplane/top/help/top.md @@ -0,0 +1,26 @@ +The `cluster top` command returns current resource utilization (CPU and memory) +by Crossplane pods. Similar to `kubectl top pods`, it requires the [Metrics +Server](https://kubernetes-sigs.github.io/metrics-server/) to be correctly +configured and working on the server. + +## Examples + +Show resource utilization for all Crossplane pods in the `crossplane-system` +namespace: + +```shell +crossplane cluster top +``` + +Show resource utilization for all Crossplane pods in the `default` namespace: + +```shell +crossplane cluster top -n default +``` + +Add a summary of resource utilization for all Crossplane pods on top of the +results: + +```shell +crossplane cluster top -s +``` diff --git a/cmd/crossplane/top/top.go b/cmd/crossplane/top/top.go index 2093667..29f61cd 100644 --- a/cmd/crossplane/top/top.go +++ b/cmd/crossplane/top/top.go @@ -35,8 +35,13 @@ import ( "github.com/crossplane/crossplane-runtime/v2/pkg/errors" "github.com/crossplane/crossplane-runtime/v2/pkg/logging" + + _ "embed" ) +//go:embed help/top.md +var helpDetail string + const ( errKubeConfig = "failed to get kubeconfig" errCreateK8sClientset = "could not create the clientset for Kubernetes" @@ -57,21 +62,7 @@ type Cmd struct { // Help returns help instructions for the top command. func (c *Cmd) Help() string { - return ` -This command returns current resources utilization (CPU and Memory) by Crossplane pods. - -Similar to kubectl top pods, it requires Metrics Server to be correctly configured and working on the server. - -Examples: - # Show resources utilization for all Crossplane pods in the default 'crossplane-system' namespace in a tabular format. - crossplane cluster top - - # Show resources utilization for all Crossplane pods in a specified namespace in a tabular format. - crossplane cluster top -n - - # Add summary of resources utilization for all Crossplane pods in the default 'crossplane-system' on top of the results. - crossplane cluster top -s -` + return helpDetail } type topMetrics struct { diff --git a/cmd/crossplane/trace/help/trace.md b/cmd/crossplane/trace/help/trace.md new file mode 100644 index 0000000..cd97412 --- /dev/null +++ b/cmd/crossplane/trace/help/trace.md @@ -0,0 +1,116 @@ +The `resource trace` command traces a Crossplane resource (Claim, Composite, or +Managed Resource) to give a detailed view of its relationships — helpful for +troubleshooting. + +The command requires a resource type and a resource name: + +```shell +crossplane resource trace +``` + +Kubernetes-style `/` input works too — for example, `crossplane +resource trace example.crossplane.io/my-xr`. + +If needed the resource kind can be specified further as +`TYPE[.VERSION][.GROUP]`, for example `mykind.example.org` or +`mykind.v1alpha1.example.org`. + +By default, `crossplane resource trace` uses the Kubernetes configuration at +`~/.kube/config`. Override with the `KUBECONFIG` environment variable. + +## Output options + +By default, `trace` prints to the terminal as a tree, truncating the `Ready` and +`Status` messages to 64 characters. + +Change the format with `-o` (`--output`): `wide`, `json`, `yaml`, or `dot` (for +a [Graphviz](https://graphviz.org/docs/layouts/dot/) graph). + +### Wide output + +Use `--output=wide` to print the full `Ready` and `Status` messages even when +they exceed 64 characters, and additional per-kind columns (for example, +composed resource names for composite resources, or image used for packages). + +### Graphviz dot output + +Use `--output=dot` to print a textual [Graphviz +dot](https://graphviz.org/docs/layouts/dot/) graph. Pipe to `dot` to render an +image: + +```shell +crossplane resource trace cluster.aws.platformref.upbound.io platform-ref-aws -o dot | dot -Tpng -o graph.png +``` + +## Print connection secrets + +Use `--show-connection-secrets` to include connection-secret names alongside the +other resources. Secret values are never printed. Output includes the secret +name and namespace. + +## Print package dependencies + +The `--show-package-dependencies` flag controls how package dependencies are +displayed: + +- `unique` (default) — include each required package only once. +- `all` — show every package that requires the same dependency. +- `none` — hide all package dependencies. + +## Print package revisions + +The `--show-package-revisions` flag controls which package revisions are shown: + +- `active` (default) — show only the active revisions. +- `all` — show all revisions, including inactive ones. +- `none` — hide all revisions. + +## Examples + +Trace a `MyKind` resource named `my-res` in the namespace `my-ns`: + +```shell +crossplane resource trace mykind my-res -n my-ns +``` + +Trace all `MyKind` resources in the namespace `my-ns`: + +```shell +crossplane resource trace mykind -n my-ns +``` + +Wide format with full errors, condition messages, and kind-specific columns: + +```shell +crossplane resource trace mykind my-res -n my-ns -o wide +``` + +Show connection secret names alongside the resources: + +```shell +crossplane resource trace mykind my-res -n my-ns --show-connection-secrets +``` + +Output a Graphviz dot graph and pipe to dot to generate a PNG: + +```shell +crossplane resource trace mykind my-res -n my-ns -o dot | dot -Tpng -o output.png +``` + +Output all retrieved resources as JSON and pipe to jq for color: + +```shell +crossplane resource trace mykind my-res -n my-ns -o json | jq +``` + +Output debug logs to stderr while piping a dot graph to dot: + +```shell +crossplane resource trace mykind my-res -n my-ns -o dot --verbose | dot -Tpng -o output.png +``` + +Watch a resource continuously until it is deleted: + +```shell +crossplane resource trace mykind my-res -n my-ns --watch +``` diff --git a/cmd/crossplane/trace/trace.go b/cmd/crossplane/trace/trace.go index 526b314..313052b 100644 --- a/cmd/crossplane/trace/trace.go +++ b/cmd/crossplane/trace/trace.go @@ -41,8 +41,13 @@ import ( "github.com/crossplane/cli/v2/cmd/crossplane/common/resource/xrm" "github.com/crossplane/cli/v2/cmd/crossplane/internal" "github.com/crossplane/cli/v2/cmd/crossplane/trace/internal/printer" + + _ "embed" ) +//go:embed help/trace.md +var helpDetail string + const ( errGetResource = "cannot get requested resource" errFmtGetResource = "cannot get requested resource: kind=%s name=%s namespace=%s (verify context, namespace, and that the resource exists)" @@ -78,40 +83,7 @@ type Cmd struct { // Help returns help message for the trace command. func (c *Cmd) Help() string { - return ` -This command trace a Crossplane resource (Claim, Composite, or Managed Resource) -to get a detailed output of its relationships, helpful for troubleshooting. - -If needed the resource kind can be also specified further, -'TYPE[.VERSION][.GROUP]', e.g. mykind.example.org or -mykind.v1alpha1.example.org. - -Examples: - # Trace a MyKind resource (mykinds.example.org/v1alpha1) named 'my-res' in the namespace 'my-ns' - crossplane resource trace mykind my-res -n my-ns - - # Trace all MyKind resources (mykinds.example.org/v1alpha1) in the namespace 'my-ns' - crossplane resource trace mykind -n my-ns - - # Output wide format, showing full errors and condition messages, and other useful info - # depending on the target type, e.g. composed resources names for composite resources or image used for packages - crossplane resource trace mykind my-res -n my-ns -o wide - - # Show connection secrets in the output - crossplane resource trace mykind my-res -n my-ns --show-connection-secrets - - # Output a graph in dot format and pipe to dot to generate a png - crossplane resource trace mykind my-res -n my-ns -o dot | dot -Tpng -o output.png - - # Output all retrieved resources to json and pipe to jq to have it coloured - crossplane resource trace mykind my-res -n my-ns -o json | jq - - # Output debug logs to stderr while redirecting a dot formatted graph to dot - crossplane resource trace mykind my-res -n my-ns -o dot --verbose | dot -Tpng -o output.png - - # Watch a resource continuously until it is deleted - crossplane resource trace mykind my-res -n my-ns --watch -` + return helpDetail } func (c *Cmd) setupKubeClient(logger logging.Logger) (clientcmd.ClientConfig, client.WithWatch, meta.RESTMapper, error) { diff --git a/cmd/crossplane/validate/cmd.go b/cmd/crossplane/validate/cmd.go index a943ab0..1220bbb 100644 --- a/cmd/crossplane/validate/cmd.go +++ b/cmd/crossplane/validate/cmd.go @@ -32,8 +32,13 @@ import ( "github.com/crossplane/crossplane-runtime/v2/pkg/version" "github.com/crossplane/cli/v2/cmd/crossplane/common/load" + + _ "embed" ) +//go:embed help/validate.md +var helpDetail string + // Cmd arguments and flags for render subcommand. type Cmd struct { // Arguments. @@ -53,40 +58,7 @@ type Cmd struct { // Help prints out the help for the validate command. func (c *Cmd) Help() string { - return ` -This command validates the provided Crossplane resources against the schemas of the provided extensions like XRDs, -CRDs, providers, functions and configurations. The output of the "crossplane composition render" command can be -piped to this validate command in order to rapidly validate on the outputs of the composition development experience. - -If providers or configurations are provided as extensions, they will be downloaded and loaded as CRDs before performing -validation. If the cache directory is not provided, it will default to "~/.crossplane/cache". -Cache directory can be cleaned before downloading schemas by setting the "clean-cache" flag. - -All validation is performed offline locally using the Kubernetes API server's validation library, so it does not require -any Crossplane instance or control plane to be running or configured. - -Examples: - - # Validate all resources in the resources.yaml file against the extensions in the extensions.yaml file - crossplane resource validate extensions.yaml resources.yaml - - # Validate all resources in the resourceDir folder against the extensions in the crossplane.yaml file and extensionsDir folder - crossplane resource validate crossplane.yaml,extensionsDir/ resourceDir/ - - # Validate all resources in the resources.yaml file against the extensions in the extensions.yaml file using a specific Crossplane image version - crossplane resource validate extensions.yaml resources.yaml --crossplane-image=xpkg.crossplane.io/crossplane/crossplane:v1.20.0 - - # Validate all resources in the resourceDir folder against the extensions in the extensionsDir folder and skip - # success logs - crossplane resource validate extensionsDir/ resourceDir/ --skip-success-results - - # Validate the output of the render command against the extensions in the extensionsDir folder - crossplane composition render xr.yaml composition.yaml func.yaml --include-full-xr | crossplane resource validate extensionsDir/ - - - # Validate all resources in the resourceDir folder against the extensions in the extensionsDir folder using provided - # cache directory and clean the cache directory before downloading schemas - crossplane resource validate extensionsDir/ resourceDir/ --cache-dir .cache --clean-cache -` + return helpDetail } // AfterApply implements kong.AfterApply. diff --git a/cmd/crossplane/validate/help/validate.md b/cmd/crossplane/validate/help/validate.md new file mode 100644 index 0000000..739eef5 --- /dev/null +++ b/cmd/crossplane/validate/help/validate.md @@ -0,0 +1,148 @@ +The `resource validate` command validates the provided Crossplane resources +against the schemas of the provided extensions (XRDs, CRDs, Providers, +Functions, and Configurations). It uses the Kubernetes API server's validation +library plus additional checks (such as unknown-field detection, a common source +of difficult-to-debug Crossplane issues). + +If Providers or Configurations are provided as extensions, they are downloaded +and loaded as CRDs before validation. If `--cache-dir` is not set, it defaults +to `~/.crossplane/cache`. Clean the cache before downloading schemas with +`--clean-cache`. + +All validation is performed offline using the Kubernetes API server's validation +library — no Crossplane instance or control plane is required. + +`crossplane resource validate` supports validating: + +- A managed or composite resource against a Provider or XRD schema. +- The output of `crossplane composition render`. +- An XRD's [Common Expression + Language](https://kubernetes.io/docs/reference/using-api/cel/) (CEL) rules. +- Resources against a directory of schemas. + +## Validate resources against a schema + +When validating against a Provider, the command downloads the Provider package +to `--cache-dir`. Access to a Kubernetes cluster or Crossplane pod is not +required — only the ability to download the Provider package. + +Create a Provider manifest: + +```yaml +apiVersion: pkg.crossplane.io/v1 +kind: Provider +metadata: + name: crossplane-contrib-provider-aws-iam +spec: + package: xpkg.crossplane.io/crossplane-contrib/provider-aws-iam:v2.0.0 +``` + +Provide a managed resource to validate: + +```yaml +apiVersion: iam.aws.m.upbound.io/v1beta1 +kind: AccessKey +metadata: + namespace: default + name: sample-access-key-0 +spec: + forProvider: + userSelector: + matchLabels: + example-name: test-user-0 +``` + +Run validate with both files: + +```shell +crossplane resource validate provider.yaml managedResource.yaml +``` + +## Validate render output + +Pipe the output of `crossplane composition render` to `validate` to check +complete Crossplane resource pipelines, including XRs, Compositions, and +Functions. Use `--include-full-xr` on `render`, and `-` (read stdin) on +`validate`: + +```shell +crossplane composition render xr.yaml composition.yaml func.yaml --include-full-xr | \ + crossplane resource validate schemas.yaml - +``` + +## Validate CEL rules + +XRDs can define [validation +rules](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation-rules) +in CEL via `x-kubernetes-validations`. `validate` evaluates them: + +```yaml +apiVersion: apiextensions.crossplane.io/v1 +kind: CompositeResourceDefinition +metadata: + name: myxrs.example.crossplane.io +spec: + # ... versions[].schema.openAPIV3Schema: + # spec: + # x-kubernetes-validations: + # - rule: "self.minReplicas <= self.replicas && self.replicas <= self.maxReplicas" + # message: "replicas should be in between minReplicas and maxReplicas." +``` + +## Validate against a directory of schemas + +`validate` can also take a directory of schema YAML files. Only `.yaml` and +`.yml` files are processed; other files are ignored. + +```text +schemas/ +├── platform-ref-aws.yaml +├── providers/ +│ └── provider-aws-iam.yaml +└── xrds/ + └── xrd.yaml +``` + +```shell +crossplane resource validate schemas/ resources.yaml +``` + +## Examples + +Validate resources against extensions in extensions.yaml: + +```shell +crossplane resource validate extensions.yaml resources.yaml +``` + +Validate resources in a directory against extensions in another directory: + +```shell +crossplane resource validate crossplane.yaml,extensionsDir/ resourceDir/ +``` + +Pin the Crossplane image version used during validation: + +```shell +crossplane resource validate extensions.yaml resources.yaml \ + --crossplane-image=xpkg.crossplane.io/crossplane/crossplane:v1.20.0 +``` + +Skip success log lines (only print problems): + +```shell +crossplane resource validate extensionsDir/ resourceDir/ --skip-success-results +``` + +Validate the output of render against extensions in a directory: + +```shell +crossplane composition render xr.yaml composition.yaml func.yaml --include-full-xr | \ + crossplane resource validate extensionsDir/ - +``` + +Use a custom cache directory and clean it before downloading schemas: + +```shell +crossplane resource validate extensionsDir/ resourceDir/ --cache-dir .cache --clean-cache +``` diff --git a/cmd/crossplane/xpkg/build.go b/cmd/crossplane/xpkg/build.go index dfdd9af..1e33556 100644 --- a/cmd/crossplane/xpkg/build.go +++ b/cmd/crossplane/xpkg/build.go @@ -34,8 +34,13 @@ import ( "github.com/crossplane/crossplane-runtime/v2/pkg/xpkg/parser" "github.com/crossplane/crossplane-runtime/v2/pkg/xpkg/parser/examples" "github.com/crossplane/crossplane-runtime/v2/pkg/xpkg/parser/yaml" + + _ "embed" ) +//go:embed help/build.md +var helpBuild string + const ( errGetNameFromMeta = "failed to get package name from crossplane.yaml" errBuildPackage = "failed to build package" @@ -108,19 +113,7 @@ type buildCmd struct { } func (c *buildCmd) Help() string { - return ` -This command builds a package file from a local directory of files. - -Examples: - - # Build a package from the files in the 'package' directory. - crossplane xpkg build --package-root=package/ - - # Build a package that embeds a Provider's controller OCI image built with - # 'docker build' so that the package can also be used to run the provider. - # Provider and Function packages support embedding runtime images. - crossplane xpkg build --embed-runtime-image=cc873e13cdc1 -` + return helpBuild } // GetRuntimeBaseImageOpts returns the controller base image options. diff --git a/cmd/crossplane/xpkg/help/build.md b/cmd/crossplane/xpkg/help/build.md new file mode 100644 index 0000000..e0abe57 --- /dev/null +++ b/cmd/crossplane/xpkg/help/build.md @@ -0,0 +1,65 @@ +The `xpkg build` command builds a package file from a local directory of +files. The CLI combines a directory of YAML files and packages them as an [OCI +container image](https://opencontainers.org/), applying the annotations and +values required by the [Crossplane XPKG +specification](https://github.com/crossplane/crossplane/blob/main/contributing/specifications/xpkg.md). + +`crossplane xpkg build` supports building Configuration, Function, and Provider +package types. + +The command recursively looks in `--package-root` for files ending in `.yml` or +`.yaml` and attempts to combine them into a package. All YAML files must be +valid Kubernetes manifests with `apiVersion`, `kind`, `metadata`, and `spec` +fields. + +## Ignore files + +Use `--ignore` to provide a comma-separated list of files and directories +(relative to `--package-root`) to skip. Wildcards are supported. Directories +themselves cannot be excluded. + +```shell +crossplane xpkg build --ignore="./test/*,kind-config.yaml" +``` + +## Set the package name + +By default the package is named from a combination of `metadata.name` and a hash +of the package contents, and written to `--package-root`. Override the location +and filename with `--package-file` (`-o`): + +```shell +crossplane xpkg build -o /home/crossplane/example.xpkg +``` + +## Include examples + +Include YAML files demonstrating how to use the package with `--examples-root` +(`-e`). Defaults to `./examples`. + +## Include a runtime image + +Function and Provider packages can embed a controller container image so that +the package can also be used to run the controller. Embedding is supported for +those package kinds only. + +> **Note:** Images referenced with `--embed-runtime-image` must be in the local +> Docker cache. Use `docker pull` to download a missing image. + +Use `--embed-runtime-image-tarball` to embed a local OCI image tarball instead +of an image from the Docker cache. + +## Examples + +Build a package from the files in the 'package' directory: + +```shell +crossplane xpkg build --package-root=package/ +``` + +Build a Provider package that embeds the controller OCI image so the package can +also run the provider. + +```shell +crossplane xpkg build --embed-runtime-image=cc873e13cdc1 +``` diff --git a/cmd/crossplane/xpkg/help/init.md b/cmd/crossplane/xpkg/help/init.md new file mode 100644 index 0000000..2a4a31b --- /dev/null +++ b/cmd/crossplane/xpkg/help/init.md @@ -0,0 +1,41 @@ +The `xpkg init` command initializes a directory that you can use to build a +package. It uses a template to initialize the directory, and can use any Git +repository as a template. + +Specify either a full Git URL or a well-known name as the template. The +following well-known template names are supported: + +%s + +## NOTES.txt + +If the template contains a `NOTES.txt` file in its root, its contents are +printed to stdout after the directory is initialized. Useful for instructions on +how to use the template. + +## init.sh + +If the template contains an `init.sh` file in its root, you are prompted to view +and/or run it. Useful for scripts that personalize the template. Pass `-r` +(`--run-init-script`) to run the script without prompting. + +## Examples + +Initialize a new Go Composition Function named function-example: + +```shell +crossplane xpkg init function-example function-template-go +``` + +Initialize a new Provider named provider-example from a custom template: + +```shell +crossplane xpkg init provider-example https://github.com/crossplane/provider-template-custom +``` + +Initialize a new Go Composition Function and run its init.sh script (if any) +without prompting or displaying its contents: + +```shell +crossplane xpkg init function-example function-template-go --run-init-script +``` diff --git a/cmd/crossplane/xpkg/help/install.md b/cmd/crossplane/xpkg/help/install.md new file mode 100644 index 0000000..292e753 --- /dev/null +++ b/cmd/crossplane/xpkg/help/install.md @@ -0,0 +1,60 @@ +The `xpkg install` command installs a package in a Crossplane control plane. It +uses `~/.kube/config` to connect to the control plane; override the path with +the `KUBECONFIG` environment variable. + +Specify the package kind, fully-qualified package OCI reference, and optionally +a name for the package inside Crossplane: + +```shell +crossplane xpkg install [] +``` + +The `` is one of `configuration`, `function`, or `provider`. + +> **Important:** The package reference must be fully qualified, including the +> registry, repository, and tag (e.g., registry.example.com/package:v1.0.0). + +## Wait for package install + +By default the command returns as soon as Crossplane accepts the package. It +does not wait for the download or install to complete. To inspect download or +installation problems, run `kubectl describe `. + +Use `--wait` (`-w`) to make the command wait for the package to become `HEALTHY` +before returning. The command returns an error if the wait time expires before +the package is healthy. + +## Require manual package activation + +Pass `-m` (`--manual-activation`) to set the package's +`revisionActivationPolicy` to `Manual`, which prevents automatic upgrades of the +package. + +## Authenticate to a private registry + +To authenticate to a private package registry use `--package-pull-secrets` with +a comma-separated list of Kubernetes Secret names. + +> **Important:** The secrets must be in the same namespace as the Crossplane +> pod. + +## Customize the number of stored package revisions + +By default Crossplane keeps only the active revision and one inactive revision +in the local package cache. Increase the number of stored revisions with `-r` +(`--revision-history-limit`). + +## Examples + +Wait 1 minute for the package to finish installing before returning: + +```shell +crossplane xpkg install provider xpkg.crossplane.io/crossplane-contrib/provider-aws-eks:v0.41.0 --wait=1m +``` + +Install a Function named function-eg using a custom runtime config: + +```shell +crossplane xpkg install function xpkg.crossplane.io/crossplane/function-example:v0.1.4 function-eg \ + --runtime-config=customconfig +``` diff --git a/cmd/crossplane/xpkg/help/push.md b/cmd/crossplane/xpkg/help/push.md new file mode 100644 index 0000000..0e04cc5 --- /dev/null +++ b/cmd/crossplane/xpkg/help/push.md @@ -0,0 +1,32 @@ +The `xpkg push` command pushes a Crossplane package file to any OCI registry. A +package's OCI tag must be a semantic version. Credentials for the registry are +retrieved from `docker` configuration; pushing to a private registry may require +a prior `docker login`. + +By default the command looks in the current directory for a single `.xpkg` file +to push. To push multiple files (e.g. a multi-platform package) or a specific +`.xpkg` file, use `-f` (`--package-files`). + +> **Important:** The destination must be fully qualified, including the +> registry, repository, and tag (e.g., registry.example.com/package:v1.0.0). + +## Examples + +Push a multi-platform package: + +```shell +crossplane xpkg push -f function-amd64.xpkg,function-arm64.xpkg \ + xpkg.crossplane.io/crossplane/function-example:v1.0.0 +``` + +Push the single xpkg file in the current directory: + +```shell +crossplane xpkg push xpkg.crossplane.io/crossplane/function-example:v1.0.0 +``` + +Push to Docker Hub: + +```shell +crossplane xpkg push docker.io/crossplane/function-example:v1.0.0 +``` diff --git a/cmd/crossplane/xpkg/help/update.md b/cmd/crossplane/xpkg/help/update.md new file mode 100644 index 0000000..6a9b060 --- /dev/null +++ b/cmd/crossplane/xpkg/help/update.md @@ -0,0 +1,27 @@ +The `xpkg update` command updates a package in a Crossplane control plane. It +uses `~/.kube/config` to connect to the control plane; override the path with +the `KUBECONFIG` environment variable. + +Specify the package kind, a new fully-qualified package OCI reference, and +optionally the name of the package already installed in Crossplane: + +```shell +crossplane xpkg update [] +``` + +> **Important:** The package reference must be fully qualified, including the +> registry, repository, and tag (e.g., registry.example.com/package:v1.0.0). + +## Examples + +Update the Function named function-eg to a new version: + +```shell +crossplane xpkg update function xpkg.crossplane.io/crossplane/function-example:v0.1.5 function-eg +``` + +Update to the latest patch version of a Provider: + +```shell +crossplane xpkg update provider xpkg.crossplane.io/crossplane-contrib/provider-aws-s3:v2.0.0 +``` diff --git a/cmd/crossplane/xpkg/help/xpkg.md b/cmd/crossplane/xpkg/help/xpkg.md new file mode 100644 index 0000000..b71f436 --- /dev/null +++ b/cmd/crossplane/xpkg/help/xpkg.md @@ -0,0 +1,11 @@ +Crossplane can be extended using packages. Crossplane packages are called +*xpkgs*. Crossplane supports Configuration, Provider, and Function packages. + +A package is an opinionated OCI image that contains everything needed to extend +a Crossplane control plane with new functionality. For example, installing a +Provider package extends Crossplane with support for new kinds of managed +resource (MR). + +See [the Crossplane packages +documentation](https://docs.crossplane.io/latest/concepts/packages) for more +information. diff --git a/cmd/crossplane/xpkg/init.go b/cmd/crossplane/xpkg/init.go index 5f4d675..d2ca280 100644 --- a/cmd/crossplane/xpkg/init.go +++ b/cmd/crossplane/xpkg/init.go @@ -34,8 +34,13 @@ import ( "github.com/crossplane/crossplane-runtime/v2/pkg/errors" "github.com/crossplane/crossplane-runtime/v2/pkg/logging" + + _ "embed" ) +//go:embed help/init.md +var helpInit string + const ( notes = "NOTES.txt" initScript = "init.sh" @@ -63,44 +68,12 @@ type initCmd struct { } func (c *initCmd) Help() string { - tpl := ` -This command initializes a directory that you can use to build a package. It -uses a template to initialize the directory. It can use any Git repository as a -template. - -You can specify either a full Git URL or a well-known name as a template. The -following well-known template names are supported: - -%s - -If the template contains NOTES.txt in its root directory, it will be -printed to stdout. This is useful for providing instructions for how -to use the template. - -If the template contains init.sh in its root directory, it will be optionally -printed out and executed. This is useful for providing a script that can be -used to initialize the package automatically. Use the -r flag to run the -script without prompting. - -Examples: - - # Initialize a new Go Composition Function named function-example. - crossplane xpkg init function-example function-template-go - - # Initialize a new Provider named provider-example from a custom template. - crossplane xpkg init provider-example https://github.com/crossplane/provider-template-custom - - # Initialize a new Go Composition Function named function-example and run - # its init.sh script (if it exists) without prompting the user or displaying its contents. - crossplane xpkg init function-example function-template-go --run-init-script -` - b := strings.Builder{} for name, url := range WellKnownTemplates() { - fmt.Fprintf(&b, " - %s (%s)\n", name, url) + fmt.Fprintf(&b, "- `%s` ([%s](%s))\n", name, url, url) } - return fmt.Sprintf(tpl, b.String()) + return fmt.Sprintf(helpInit, b.String()) } func (c *initCmd) Run(k *kong.Context, logger logging.Logger) error { diff --git a/cmd/crossplane/xpkg/install.go b/cmd/crossplane/xpkg/install.go index b67b193..dcced16 100644 --- a/cmd/crossplane/xpkg/install.go +++ b/cmd/crossplane/xpkg/install.go @@ -40,10 +40,14 @@ import ( v1 "github.com/crossplane/crossplane/apis/v2/pkg/v1" "github.com/crossplane/crossplane/apis/v2/pkg/v1beta1" + _ "embed" // Load all the auth plugins for the cloud providers. _ "k8s.io/client-go/plugin/pkg/client/auth" ) +//go:embed help/install.md +var helpInstall string + const ( errPkgIdentifier = "invalid package image identifier" errKubeConfig = "failed to get kubeconfig" @@ -66,23 +70,7 @@ type installCmd struct { } func (c *installCmd) Help() string { - return ` -This command installs a package in a Crossplane control plane. It uses -~/.kube/config to connect to the control plane. You can override this using the -KUBECONFIG environment variable. - -IMPORTANT: the package must be fully qualified, including the registry, repository, and tag. - -Examples: - - # Wait 1 minute for the package to finish installing before returning. - crossplane xpkg install provider xpkg.crossplane.io/crossplane-contrib/provider-aws-eks:v0.41.0 --wait=1m - - # Install a Function named function-eg that uses a runtime config named - # customconfig. - crossplane xpkg install function xpkg.crossplane.io/crossplane/function-example:v0.1.4 function-eg \ - --runtime-config=customconfig -` + return helpInstall } // Run the package install cmd. diff --git a/cmd/crossplane/xpkg/push.go b/cmd/crossplane/xpkg/push.go index 48eeffd..42b6ddb 100644 --- a/cmd/crossplane/xpkg/push.go +++ b/cmd/crossplane/xpkg/push.go @@ -37,8 +37,13 @@ import ( "github.com/crossplane/crossplane-runtime/v2/pkg/errors" "github.com/crossplane/crossplane-runtime/v2/pkg/logging" "github.com/crossplane/crossplane-runtime/v2/pkg/xpkg" + + _ "embed" ) +//go:embed help/push.md +var helpPush string + const ( errGetwd = "failed to get working directory while searching for package" errFindPackageinWd = "failed to find a package in current working directory" @@ -68,21 +73,7 @@ type pushCmd struct { } func (c *pushCmd) Help() string { - return ` -Packages can be pushed to any OCI registry. A package's OCI tag must be a semantic -version. Credentials for the registry are automatically retrieved from xpkg login -and dockers configuration as fallback. - -IMPORTANT: the package must be fully qualified, including the registry, repository, and tag. - -Examples: - - # Push a multi-platform package. - crossplane xpkg push -f function-amd64.xpkg,function-arm64.xpkg xpkg.crossplane.io/crossplane/function-example:v1.0.0 - - # Push the xpkg file in the current directory to a different registry. - crossplane xpkg push index.docker.io/crossplane/function-example:v1.0.0 -` + return helpPush } // AfterApply sets the tag for the parent push command. diff --git a/cmd/crossplane/xpkg/update.go b/cmd/crossplane/xpkg/update.go index f1ce7d7..25356a3 100644 --- a/cmd/crossplane/xpkg/update.go +++ b/cmd/crossplane/xpkg/update.go @@ -36,9 +36,13 @@ import ( v1 "github.com/crossplane/crossplane/apis/v2/pkg/v1" "github.com/crossplane/crossplane/apis/v2/pkg/v1beta1" + _ "embed" _ "k8s.io/client-go/plugin/pkg/client/auth" // Load all the auth plugins for the cloud providers. ) +//go:embed help/update.md +var helpUpdate string + // updateCmd updates a package. type updateCmd struct { // Arguments. @@ -48,18 +52,7 @@ type updateCmd struct { } func (c *updateCmd) Help() string { - return ` -This command updates a package in a Crossplane control plane. It uses -~/.kube/config to connect to the control plane. You can override this using the -KUBECONFIG environment variable. - -IMPORTANT: the package must be fully qualified, including the registry, repository, and tag. - -Examples: - - # Update the Function named function-eg - crossplane xpkg update function xpkg.crossplane.io/crossplane/function-example:v0.1.5 function-eg -` + return helpUpdate } // Run the package update cmd. diff --git a/cmd/crossplane/xpkg/xpkg.go b/cmd/crossplane/xpkg/xpkg.go index c12a4e7..35f6e38 100644 --- a/cmd/crossplane/xpkg/xpkg.go +++ b/cmd/crossplane/xpkg/xpkg.go @@ -17,6 +17,11 @@ limitations under the License. // Package xpkg contains Crossplane packaging commands. package xpkg +import _ "embed" + +//go:embed help/xpkg.md +var helpXpkg string + // TODO(lsviben) add the rest of the commands from up (batch, xpextract). // Cmd contains commands for interacting with xpkgs. @@ -33,15 +38,5 @@ type Cmd struct { // Help prints out the help for the xpkg command. func (c *Cmd) Help() string { - return ` -Crossplane can be extended using packages. Crossplane packages are called xpkgs. -Crossplane supports configuration, provider and function packages. - -A package is an opinionated OCI image that contains everything needed to extend -a Crossplane control plane with new functionality. For example installing a -provider package extends Crossplane with support for new kinds of managed -resource (MR). - -See https://docs.crossplane.io/latest/concepts/packages for more information. -` + return helpXpkg } diff --git a/go.mod b/go.mod index 4c133a4..bc80bcd 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,8 @@ require ( github.com/Masterminds/semver/v3 v3.4.0 github.com/alecthomas/kong v1.14.0 github.com/charmbracelet/bubbletea v1.3.10 + github.com/charmbracelet/glamour v1.0.0 + github.com/charmbracelet/x/term v0.2.2 github.com/containerd/errdefs v1.0.0 github.com/crossplane/crossplane-runtime/v2 v2.3.0-rc.0.0.20260504135302-a596e1f75635 github.com/crossplane/crossplane/apis/v2 v2.0.0-20260424160951-8f231230ebb6 @@ -19,6 +21,7 @@ require ( github.com/go-git/go-git/v5 v5.18.0 github.com/google/go-cmp v0.7.0 github.com/google/go-containerregistry v0.21.2 + github.com/muesli/termenv v0.16.0 github.com/pkg/errors v0.9.1 github.com/posener/complete v1.2.3 github.com/spf13/afero v1.15.0 @@ -55,6 +58,7 @@ require ( github.com/Azure/go-autorest/tracing v0.6.1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProtonMail/go-crypto v1.1.6 // indirect + github.com/alecthomas/chroma/v2 v2.20.0 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/aws/aws-sdk-go-v2 v1.41.4 // indirect @@ -75,16 +79,17 @@ require ( github.com/aws/smithy-go v1.24.2 // indirect github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.12.0 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver v3.5.1+incompatible // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/charmbracelet/colorprofile v0.4.1 // indirect - github.com/charmbracelet/lipgloss v1.1.0 // indirect + github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 // indirect github.com/charmbracelet/x/ansi v0.11.6 // indirect github.com/charmbracelet/x/cellbuf v0.0.15 // indirect - github.com/charmbracelet/x/term v0.2.2 // indirect + github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf // indirect github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 // indirect github.com/clipperhouse/displaywidth v0.9.0 // indirect github.com/clipperhouse/stringish v0.1.1 // indirect @@ -100,6 +105,7 @@ require ( github.com/digitorus/timestamp v0.0.0-20250524132541-c45532741eea // indirect github.com/dimchansky/utfbom v1.1.1 // indirect github.com/distribution/reference v0.6.0 // indirect + github.com/dlclark/regexp2 v1.11.5 // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker-credential-helpers v0.9.5 // indirect github.com/docker/go-units v0.5.0 // indirect @@ -152,6 +158,7 @@ require ( github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20230919002926-dbcd01c402b2 // indirect github.com/google/go-containerregistry/pkg/authn/kubernetes v0.0.0-20250225234217-098045d5e61f // indirect github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/css v1.0.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -172,6 +179,7 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.19 // indirect + github.com/microcosm-cc/bluemonday v1.0.27 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/sys/sequential v0.6.0 // indirect @@ -180,7 +188,7 @@ require ( github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect - github.com/muesli/termenv v0.16.0 // indirect + github.com/muesli/reflow v0.3.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 // indirect github.com/oklog/ulid/v2 v2.1.1 // indirect @@ -222,6 +230,8 @@ require ( github.com/x448/float16 v0.8.4 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + github.com/yuin/goldmark v1.7.13 // indirect + github.com/yuin/goldmark-emoji v1.0.6 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect diff --git a/go.sum b/go.sum index 5c8d72f..7dd9c7f 100644 --- a/go.sum +++ b/go.sum @@ -73,6 +73,8 @@ github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNx github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= +github.com/alecthomas/chroma/v2 v2.20.0 h1:sfIHpxPyR07/Oylvmcai3X/exDlE8+FA820NTz+9sGw= +github.com/alecthomas/chroma/v2 v2.20.0/go.mod h1:e7tViK0xh/Nf4BYHl00ycY6rV7b8iXBksI9E359yNmA= github.com/alecthomas/kong v1.14.0 h1:gFgEUZWu2ZmZ+UhyZ1bDhuutbKN1nTtJTwh19Wsn21s= github.com/alecthomas/kong v1.14.0/go.mod h1:wrlbXem1CWqUV5Vbmss5ISYhsVPkBb1Yo7YKJghju2I= github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs= @@ -127,6 +129,10 @@ github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.12.0 h1:JFWXO6QPihC github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.12.0/go.mod h1:046/oLyFlYdAghYQE2yHXi/E//VM5Cf3/dFmA+3CZ0c= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8= +github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= @@ -143,12 +149,18 @@ github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlv github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk= github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk= -github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= -github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= +github.com/charmbracelet/glamour v1.0.0 h1:AWMLOVFHTsysl4WV8T8QgkQ0s/ZNZo7CiE4WKhk8l08= +github.com/charmbracelet/glamour v1.0.0/go.mod h1:DSdohgOBkMr2ZQNhw4LZxSGpx3SvpeujNoXrQyH2hxo= +github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 h1:ZR7e0ro+SZZiIZD7msJyA+NjkCNNavuiPBLgerbOziE= +github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834/go.mod h1:aKC/t2arECF6rNOnaKaVU6y4t4ZeHQzqfxedE/VkVhA= github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8= github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ= github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI= github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q= +github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a h1:G99klV19u0QnhiizODirwVksQB91TJKV/UaTnACcG30= +github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U= +github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf h1:rLG0Yb6MQSDKdB52aGX55JT1oi0P0Kuaj7wi1bLUpnI= +github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf/go.mod h1:B3UgsnsBZS/eX42BlaNiJkD1pPOUa+oF1IYC6Yd2CEU= github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 h1:krfRl01rzPzxSxyLyrChD+U+MzsBXbm0OwYYB67uF+4= @@ -208,6 +220,8 @@ github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= +github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/docker/cli v29.4.0+incompatible h1:+IjXULMetlvWJiuSI0Nbor36lcJ5BTcVpUmB21KBoVM= github.com/docker/cli v29.4.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= @@ -392,6 +406,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.14 h1:yh8ncqsbUY4shRD5dA github.com/googleapis/enterprise-certificate-proxy v0.3.14/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg= github.com/googleapis/gax-go/v2 v2.19.0 h1:fYQaUOiGwll0cGj7jmHT/0nPlcrZDFPrZRhTsoCr8hE= github.com/googleapis/gax-go/v2 v2.19.0/go.mod h1:w2ROXVdfGEVFXzmlciUU4EdjHgWvB5h2n6x/8XSTTJA= +github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= +github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= @@ -481,8 +497,11 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= +github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= +github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= +github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c h1:cqn374mizHuIWj+OSJCajGr/phAmuMug9qIX3l9CflE= @@ -507,6 +526,8 @@ github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= +github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= +github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= @@ -559,6 +580,8 @@ github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTU github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/riywo/loginshell v0.0.0-20200815045211-7d26008be1ab h1:ZjX6I48eZSFetPb41dHudEyVr5v953N15TsNZXlkcWY= @@ -670,6 +693,10 @@ github.com/ysmood/leakless v0.9.0 h1:qxCG5VirSBvmi3uynXFkcnLMzkphdh3xx5FtrORwDCU github.com/ysmood/leakless v0.9.0/go.mod h1:R8iAXPRaG97QJwqxs74RdwzcRHT1SWCGTNqY8q0JvMQ= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= +github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= +github.com/yuin/goldmark-emoji v1.0.6 h1:QWfF2FYaXwL74tfGOW5izeiZepUDroDJfWubQI9HTHs= +github.com/yuin/goldmark-emoji v1.0.6/go.mod h1:ukxJDKFpdFb5x0a5HqbdlcKtebh086iJpI31LTKmWuA= github.com/zalando/go-keyring v0.2.3 h1:v9CUu9phlABObO4LPWycf+zwMG7nlbb3t/B5wa97yms= github.com/zalando/go-keyring v0.2.3/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= go.etcd.io/etcd/api/v3 v3.6.8 h1:gqb1VN92TAI6G2FiBvWcqKtHiIjr4SU2GdXxTwyexbM= diff --git a/gomod2nix.toml b/gomod2nix.toml index f01ddbf..844fd86 100644 --- a/gomod2nix.toml +++ b/gomod2nix.toml @@ -1,5 +1,5 @@ schema = 3 -cachePackages = ["cel.dev/expr", "cloud.google.com/go/compute/metadata", "dario.cat/mergo", "github.com/Azure/azure-sdk-for-go/services/preview/containerregistry/runtime/2019-08-15-preview/containerregistry", "github.com/Azure/azure-sdk-for-go/version", "github.com/Azure/go-autorest/autorest", "github.com/Azure/go-autorest/autorest/adal", "github.com/Azure/go-autorest/autorest/azure", "github.com/Azure/go-autorest/autorest/azure/auth", "github.com/Azure/go-autorest/autorest/azure/cli", "github.com/Azure/go-autorest/autorest/date", "github.com/Azure/go-autorest/logger", "github.com/Azure/go-autorest/tracing", "github.com/Masterminds/semver/v3", "github.com/ProtonMail/go-crypto/bitcurves", "github.com/ProtonMail/go-crypto/brainpool", "github.com/ProtonMail/go-crypto/eax", "github.com/ProtonMail/go-crypto/ocb", "github.com/ProtonMail/go-crypto/openpgp", "github.com/ProtonMail/go-crypto/openpgp/aes/keywrap", "github.com/ProtonMail/go-crypto/openpgp/armor", "github.com/ProtonMail/go-crypto/openpgp/ecdh", "github.com/ProtonMail/go-crypto/openpgp/ecdsa", "github.com/ProtonMail/go-crypto/openpgp/ed25519", "github.com/ProtonMail/go-crypto/openpgp/ed448", "github.com/ProtonMail/go-crypto/openpgp/eddsa", "github.com/ProtonMail/go-crypto/openpgp/elgamal", "github.com/ProtonMail/go-crypto/openpgp/errors", "github.com/ProtonMail/go-crypto/openpgp/packet", "github.com/ProtonMail/go-crypto/openpgp/s2k", "github.com/ProtonMail/go-crypto/openpgp/x25519", "github.com/ProtonMail/go-crypto/openpgp/x448", "github.com/alecthomas/kong", "github.com/antlr4-go/antlr/v4", "github.com/asaskevich/govalidator", "github.com/aws/aws-sdk-go-v2/aws", "github.com/aws/aws-sdk-go-v2/aws/defaults", "github.com/aws/aws-sdk-go-v2/aws/middleware", "github.com/aws/aws-sdk-go-v2/aws/protocol/query", "github.com/aws/aws-sdk-go-v2/aws/protocol/restjson", "github.com/aws/aws-sdk-go-v2/aws/protocol/xml", "github.com/aws/aws-sdk-go-v2/aws/ratelimit", "github.com/aws/aws-sdk-go-v2/aws/retry", "github.com/aws/aws-sdk-go-v2/aws/signer/v4", "github.com/aws/aws-sdk-go-v2/aws/transport/http", "github.com/aws/aws-sdk-go-v2/config", "github.com/aws/aws-sdk-go-v2/credentials", "github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds", "github.com/aws/aws-sdk-go-v2/credentials/endpointcreds", "github.com/aws/aws-sdk-go-v2/credentials/logincreds", "github.com/aws/aws-sdk-go-v2/credentials/processcreds", "github.com/aws/aws-sdk-go-v2/credentials/ssocreds", "github.com/aws/aws-sdk-go-v2/credentials/stscreds", "github.com/aws/aws-sdk-go-v2/feature/ec2/imds", "github.com/aws/aws-sdk-go-v2/service/ecr", "github.com/aws/aws-sdk-go-v2/service/ecr/types", "github.com/aws/aws-sdk-go-v2/service/ecrpublic", "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types", "github.com/aws/aws-sdk-go-v2/service/signin", "github.com/aws/aws-sdk-go-v2/service/signin/types", "github.com/aws/aws-sdk-go-v2/service/sso", "github.com/aws/aws-sdk-go-v2/service/sso/types", "github.com/aws/aws-sdk-go-v2/service/ssooidc", "github.com/aws/aws-sdk-go-v2/service/ssooidc/types", "github.com/aws/aws-sdk-go-v2/service/sts", "github.com/aws/aws-sdk-go-v2/service/sts/types", "github.com/aws/smithy-go", "github.com/aws/smithy-go/auth", "github.com/aws/smithy-go/auth/bearer", "github.com/aws/smithy-go/context", "github.com/aws/smithy-go/document", "github.com/aws/smithy-go/encoding", "github.com/aws/smithy-go/encoding/httpbinding", "github.com/aws/smithy-go/encoding/json", "github.com/aws/smithy-go/encoding/xml", "github.com/aws/smithy-go/endpoints", "github.com/aws/smithy-go/endpoints/private/rulesfn", "github.com/aws/smithy-go/io", "github.com/aws/smithy-go/logging", "github.com/aws/smithy-go/metrics", "github.com/aws/smithy-go/middleware", "github.com/aws/smithy-go/private/requestcompression", "github.com/aws/smithy-go/ptr", "github.com/aws/smithy-go/rand", "github.com/aws/smithy-go/time", "github.com/aws/smithy-go/tracing", "github.com/aws/smithy-go/transport/http", "github.com/aws/smithy-go/waiter", "github.com/awslabs/amazon-ecr-credential-helper/ecr-login", "github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api", "github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cache", "github.com/awslabs/amazon-ecr-credential-helper/ecr-login/config", "github.com/awslabs/amazon-ecr-credential-helper/ecr-login/version", "github.com/aymanbagabas/go-osc52/v2", "github.com/beorn7/perks/quantile", "github.com/blang/semver", "github.com/blang/semver/v4", "github.com/cenkalti/backoff/v5", "github.com/cespare/xxhash/v2", "github.com/charmbracelet/bubbletea", "github.com/charmbracelet/colorprofile", "github.com/charmbracelet/lipgloss", "github.com/charmbracelet/x/ansi", "github.com/charmbracelet/x/ansi/parser", "github.com/charmbracelet/x/cellbuf", "github.com/charmbracelet/x/term", "github.com/chrismellard/docker-credential-acr-env/pkg/credhelper", "github.com/chrismellard/docker-credential-acr-env/pkg/registry", "github.com/chrismellard/docker-credential-acr-env/pkg/token", "github.com/clipperhouse/displaywidth", "github.com/clipperhouse/stringish", "github.com/clipperhouse/uax29/v2/graphemes", "github.com/cloudflare/circl/dh/x25519", "github.com/cloudflare/circl/dh/x448", "github.com/cloudflare/circl/ecc/goldilocks", "github.com/cloudflare/circl/math", "github.com/cloudflare/circl/math/fp25519", "github.com/cloudflare/circl/math/fp448", "github.com/cloudflare/circl/math/mlsbset", "github.com/cloudflare/circl/sign", "github.com/cloudflare/circl/sign/ed25519", "github.com/cloudflare/circl/sign/ed448", "github.com/containerd/errdefs", "github.com/containerd/errdefs/pkg/errhttp", "github.com/containerd/stargz-snapshotter/estargz", "github.com/containerd/stargz-snapshotter/estargz/errorutil", "github.com/coreos/go-oidc/v3/oidc", "github.com/crossplane/crossplane-runtime/v2/pkg/errors", "github.com/crossplane/crossplane-runtime/v2/pkg/fieldpath", "github.com/crossplane/crossplane-runtime/v2/pkg/logging", "github.com/crossplane/crossplane-runtime/v2/pkg/meta", "github.com/crossplane/crossplane-runtime/v2/pkg/resource", "github.com/crossplane/crossplane-runtime/v2/pkg/resource/unstructured", "github.com/crossplane/crossplane-runtime/v2/pkg/resource/unstructured/claim", "github.com/crossplane/crossplane-runtime/v2/pkg/resource/unstructured/composed", "github.com/crossplane/crossplane-runtime/v2/pkg/resource/unstructured/composite", "github.com/crossplane/crossplane-runtime/v2/pkg/resource/unstructured/reference", "github.com/crossplane/crossplane-runtime/v2/pkg/test", "github.com/crossplane/crossplane-runtime/v2/pkg/version", "github.com/crossplane/crossplane-runtime/v2/pkg/xcrd", "github.com/crossplane/crossplane-runtime/v2/pkg/xpkg", "github.com/crossplane/crossplane-runtime/v2/pkg/xpkg/parser", "github.com/crossplane/crossplane-runtime/v2/pkg/xpkg/parser/examples", "github.com/crossplane/crossplane-runtime/v2/pkg/xpkg/parser/yaml", "github.com/crossplane/crossplane-runtime/v2/pkg/xpkg/signature", "github.com/crossplane/crossplane/apis/v2/apiextensions/v1", "github.com/crossplane/crossplane/apis/v2/apiextensions/v1alpha1", "github.com/crossplane/crossplane/apis/v2/apiextensions/v1beta1", "github.com/crossplane/crossplane/apis/v2/apiextensions/v2", "github.com/crossplane/crossplane/apis/v2/core/v2", "github.com/crossplane/crossplane/apis/v2/ops/v1alpha1", "github.com/crossplane/crossplane/apis/v2/pkg", "github.com/crossplane/crossplane/apis/v2/pkg/meta/v1", "github.com/crossplane/crossplane/apis/v2/pkg/meta/v1alpha1", "github.com/crossplane/crossplane/apis/v2/pkg/meta/v1beta1", "github.com/crossplane/crossplane/apis/v2/pkg/v1", "github.com/crossplane/crossplane/apis/v2/pkg/v1beta1", "github.com/crossplane/function-sdk-go/errors", "github.com/crossplane/function-sdk-go/proto/v1", "github.com/crossplane/function-sdk-go/resource", "github.com/crossplane/function-sdk-go/resource/composed", "github.com/crossplane/function-sdk-go/resource/composite", "github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer", "github.com/cyphar/filepath-securejoin", "github.com/davecgh/go-spew/spew", "github.com/digitorus/pkcs7", "github.com/digitorus/timestamp", "github.com/dimchansky/utfbom", "github.com/distribution/reference", "github.com/docker/cli/cli/config", "github.com/docker/cli/cli/config/configfile", "github.com/docker/cli/cli/config/credentials", "github.com/docker/cli/cli/config/memorystore", "github.com/docker/cli/cli/config/types", "github.com/docker/distribution/registry/client/auth/challenge", "github.com/docker/docker-credential-helpers/client", "github.com/docker/docker-credential-helpers/credentials", "github.com/docker/docker/api", "github.com/docker/docker/api/types", "github.com/docker/docker/api/types/blkiodev", "github.com/docker/docker/api/types/build", "github.com/docker/docker/api/types/checkpoint", "github.com/docker/docker/api/types/common", "github.com/docker/docker/api/types/container", "github.com/docker/docker/api/types/events", "github.com/docker/docker/api/types/filters", "github.com/docker/docker/api/types/image", "github.com/docker/docker/api/types/mount", "github.com/docker/docker/api/types/network", "github.com/docker/docker/api/types/registry", "github.com/docker/docker/api/types/storage", "github.com/docker/docker/api/types/strslice", "github.com/docker/docker/api/types/swarm", "github.com/docker/docker/api/types/swarm/runtime", "github.com/docker/docker/api/types/system", "github.com/docker/docker/api/types/time", "github.com/docker/docker/api/types/versions", "github.com/docker/docker/api/types/volume", "github.com/docker/docker/client", "github.com/docker/docker/pkg/stdcopy", "github.com/docker/go-connections/nat", "github.com/docker/go-connections/sockets", "github.com/docker/go-connections/tlsconfig", "github.com/docker/go-units", "github.com/dustin/go-humanize", "github.com/emicklei/dot", "github.com/emicklei/go-restful/v3", "github.com/emicklei/go-restful/v3/log", "github.com/emirpasic/gods/containers", "github.com/emirpasic/gods/lists", "github.com/emirpasic/gods/lists/arraylist", "github.com/emirpasic/gods/trees", "github.com/emirpasic/gods/trees/binaryheap", "github.com/emirpasic/gods/utils", "github.com/evanphx/json-patch/v5", "github.com/felixge/httpsnoop", "github.com/fsnotify/fsnotify", "github.com/fxamacker/cbor/v2", "github.com/go-chi/chi/v5", "github.com/go-chi/chi/v5/middleware", "github.com/go-git/gcfg", "github.com/go-git/gcfg/scanner", "github.com/go-git/gcfg/token", "github.com/go-git/gcfg/types", "github.com/go-git/go-billy/v5", "github.com/go-git/go-billy/v5/helper/chroot", "github.com/go-git/go-billy/v5/helper/polyfill", "github.com/go-git/go-billy/v5/osfs", "github.com/go-git/go-billy/v5/util", "github.com/go-git/go-git/v5", "github.com/go-git/go-git/v5/config", "github.com/go-git/go-git/v5/plumbing", "github.com/go-git/go-git/v5/plumbing/cache", "github.com/go-git/go-git/v5/plumbing/color", "github.com/go-git/go-git/v5/plumbing/filemode", "github.com/go-git/go-git/v5/plumbing/format/config", "github.com/go-git/go-git/v5/plumbing/format/diff", "github.com/go-git/go-git/v5/plumbing/format/gitignore", "github.com/go-git/go-git/v5/plumbing/format/idxfile", "github.com/go-git/go-git/v5/plumbing/format/index", "github.com/go-git/go-git/v5/plumbing/format/objfile", "github.com/go-git/go-git/v5/plumbing/format/packfile", "github.com/go-git/go-git/v5/plumbing/format/pktline", "github.com/go-git/go-git/v5/plumbing/hash", "github.com/go-git/go-git/v5/plumbing/object", "github.com/go-git/go-git/v5/plumbing/protocol/packp", "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability", "github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband", "github.com/go-git/go-git/v5/plumbing/revlist", "github.com/go-git/go-git/v5/plumbing/storer", "github.com/go-git/go-git/v5/plumbing/transport", "github.com/go-git/go-git/v5/plumbing/transport/client", "github.com/go-git/go-git/v5/plumbing/transport/file", "github.com/go-git/go-git/v5/plumbing/transport/git", "github.com/go-git/go-git/v5/plumbing/transport/http", "github.com/go-git/go-git/v5/plumbing/transport/server", "github.com/go-git/go-git/v5/plumbing/transport/ssh", "github.com/go-git/go-git/v5/storage", "github.com/go-git/go-git/v5/storage/filesystem", "github.com/go-git/go-git/v5/storage/filesystem/dotgit", "github.com/go-git/go-git/v5/storage/memory", "github.com/go-git/go-git/v5/utils/binary", "github.com/go-git/go-git/v5/utils/diff", "github.com/go-git/go-git/v5/utils/ioutil", "github.com/go-git/go-git/v5/utils/merkletrie", "github.com/go-git/go-git/v5/utils/merkletrie/filesystem", "github.com/go-git/go-git/v5/utils/merkletrie/index", "github.com/go-git/go-git/v5/utils/merkletrie/noder", "github.com/go-git/go-git/v5/utils/sync", "github.com/go-git/go-git/v5/utils/trace", "github.com/go-jose/go-jose/v4", "github.com/go-jose/go-jose/v4/cipher", "github.com/go-jose/go-jose/v4/json", "github.com/go-json-experiment/json", "github.com/go-json-experiment/json/jsontext", "github.com/go-logr/logr", "github.com/go-logr/logr/funcr", "github.com/go-logr/logr/slogr", "github.com/go-logr/stdr", "github.com/go-logr/zapr", "github.com/go-openapi/analysis", "github.com/go-openapi/errors", "github.com/go-openapi/jsonpointer", "github.com/go-openapi/jsonreference", "github.com/go-openapi/loads", "github.com/go-openapi/runtime", "github.com/go-openapi/runtime/client", "github.com/go-openapi/runtime/logger", "github.com/go-openapi/runtime/middleware", "github.com/go-openapi/runtime/middleware/denco", "github.com/go-openapi/runtime/middleware/header", "github.com/go-openapi/runtime/middleware/untyped", "github.com/go-openapi/runtime/security", "github.com/go-openapi/runtime/yamlpc", "github.com/go-openapi/spec", "github.com/go-openapi/strfmt", "github.com/go-openapi/swag", "github.com/go-openapi/swag/cmdutils", "github.com/go-openapi/swag/conv", "github.com/go-openapi/swag/fileutils", "github.com/go-openapi/swag/jsonname", "github.com/go-openapi/swag/jsonutils", "github.com/go-openapi/swag/jsonutils/adapters", "github.com/go-openapi/swag/jsonutils/adapters/ifaces", "github.com/go-openapi/swag/jsonutils/adapters/stdlib/json", "github.com/go-openapi/swag/loading", "github.com/go-openapi/swag/mangling", "github.com/go-openapi/swag/netutils", "github.com/go-openapi/swag/stringutils", "github.com/go-openapi/swag/typeutils", "github.com/go-openapi/swag/yamlutils", "github.com/go-openapi/validate", "github.com/go-viper/mapstructure/v2", "github.com/golang-jwt/jwt/v4", "github.com/golang/groupcache/lru", "github.com/golang/snappy", "github.com/google/btree", "github.com/google/cel-go/cel", "github.com/google/cel-go/checker", "github.com/google/cel-go/checker/decls", "github.com/google/cel-go/common", "github.com/google/cel-go/common/ast", "github.com/google/cel-go/common/containers", "github.com/google/cel-go/common/debug", "github.com/google/cel-go/common/decls", "github.com/google/cel-go/common/env", "github.com/google/cel-go/common/functions", "github.com/google/cel-go/common/operators", "github.com/google/cel-go/common/overloads", "github.com/google/cel-go/common/runes", "github.com/google/cel-go/common/stdlib", "github.com/google/cel-go/common/types", "github.com/google/cel-go/common/types/pb", "github.com/google/cel-go/common/types/ref", "github.com/google/cel-go/common/types/traits", "github.com/google/cel-go/ext", "github.com/google/cel-go/interpreter", "github.com/google/cel-go/interpreter/functions", "github.com/google/cel-go/parser", "github.com/google/cel-go/parser/gen", "github.com/google/certificate-transparency-go", "github.com/google/certificate-transparency-go/asn1", "github.com/google/certificate-transparency-go/client", "github.com/google/certificate-transparency-go/client/configpb", "github.com/google/certificate-transparency-go/ctutil", "github.com/google/certificate-transparency-go/gossip/minimal/x509ext", "github.com/google/certificate-transparency-go/jsonclient", "github.com/google/certificate-transparency-go/loglist3", "github.com/google/certificate-transparency-go/tls", "github.com/google/certificate-transparency-go/x509", "github.com/google/certificate-transparency-go/x509/pkix", "github.com/google/certificate-transparency-go/x509util", "github.com/google/gnostic-models/compiler", "github.com/google/gnostic-models/extensions", "github.com/google/gnostic-models/jsonschema", "github.com/google/gnostic-models/openapiv2", "github.com/google/gnostic-models/openapiv3", "github.com/google/go-cmp/cmp", "github.com/google/go-cmp/cmp/cmpopts", "github.com/google/go-containerregistry/pkg/authn", "github.com/google/go-containerregistry/pkg/authn/k8schain", "github.com/google/go-containerregistry/pkg/authn/kubernetes", "github.com/google/go-containerregistry/pkg/compression", "github.com/google/go-containerregistry/pkg/crane", "github.com/google/go-containerregistry/pkg/legacy", "github.com/google/go-containerregistry/pkg/legacy/tarball", "github.com/google/go-containerregistry/pkg/logs", "github.com/google/go-containerregistry/pkg/name", "github.com/google/go-containerregistry/pkg/v1", "github.com/google/go-containerregistry/pkg/v1/daemon", "github.com/google/go-containerregistry/pkg/v1/empty", "github.com/google/go-containerregistry/pkg/v1/google", "github.com/google/go-containerregistry/pkg/v1/layout", "github.com/google/go-containerregistry/pkg/v1/match", "github.com/google/go-containerregistry/pkg/v1/mutate", "github.com/google/go-containerregistry/pkg/v1/partial", "github.com/google/go-containerregistry/pkg/v1/random", "github.com/google/go-containerregistry/pkg/v1/remote", "github.com/google/go-containerregistry/pkg/v1/remote/transport", "github.com/google/go-containerregistry/pkg/v1/static", "github.com/google/go-containerregistry/pkg/v1/stream", "github.com/google/go-containerregistry/pkg/v1/tarball", "github.com/google/go-containerregistry/pkg/v1/types", "github.com/google/uuid", "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options", "github.com/grpc-ecosystem/grpc-gateway/v2/runtime", "github.com/grpc-ecosystem/grpc-gateway/v2/utilities", "github.com/hashicorp/errwrap", "github.com/hashicorp/go-cleanhttp", "github.com/hashicorp/go-multierror", "github.com/hashicorp/go-retryablehttp", "github.com/in-toto/attestation/go/v1", "github.com/in-toto/in-toto-golang/in_toto", "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common", "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.1", "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2", "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1", "github.com/jbenet/go-context/io", "github.com/jedisct1/go-minisign", "github.com/json-iterator/go", "github.com/kevinburke/ssh_config", "github.com/klauspost/compress", "github.com/klauspost/compress/fse", "github.com/klauspost/compress/huff0", "github.com/klauspost/compress/zstd", "github.com/letsencrypt/boulder/core", "github.com/letsencrypt/boulder/core/proto", "github.com/letsencrypt/boulder/goodkey", "github.com/letsencrypt/boulder/identifier", "github.com/letsencrypt/boulder/probs", "github.com/letsencrypt/boulder/revocation", "github.com/liggitt/tabwriter", "github.com/lucasb-eyer/go-colorful", "github.com/mattn/go-isatty", "github.com/mattn/go-runewidth", "github.com/mitchellh/go-homedir", "github.com/moby/docker-image-spec/specs-go/v1", "github.com/moby/term", "github.com/modern-go/concurrent", "github.com/modern-go/reflect2", "github.com/muesli/ansi", "github.com/muesli/ansi/compressor", "github.com/muesli/cancelreader", "github.com/muesli/termenv", "github.com/munnerz/goautoneg", "github.com/nozzle/throttler", "github.com/oklog/ulid/v2", "github.com/opencontainers/go-digest", "github.com/opencontainers/image-spec/specs-go", "github.com/opencontainers/image-spec/specs-go/v1", "github.com/pjbgf/sha1cd", "github.com/pjbgf/sha1cd/ubc", "github.com/pkg/browser", "github.com/pkg/errors", "github.com/pmezard/go-difflib/difflib", "github.com/posener/complete", "github.com/posener/complete/cmd", "github.com/posener/complete/cmd/install", "github.com/prometheus/client_golang/prometheus", "github.com/prometheus/client_golang/prometheus/collectors", "github.com/prometheus/client_golang/prometheus/promhttp", "github.com/prometheus/client_model/go", "github.com/prometheus/common/expfmt", "github.com/prometheus/common/model", "github.com/prometheus/procfs", "github.com/rivo/uniseg", "github.com/riywo/loginshell", "github.com/sassoftware/relic/lib/pkcs7", "github.com/sassoftware/relic/lib/x509tools", "github.com/secure-systems-lab/go-securesystemslib/cjson", "github.com/secure-systems-lab/go-securesystemslib/dsse", "github.com/secure-systems-lab/go-securesystemslib/encrypted", "github.com/secure-systems-lab/go-securesystemslib/signerverifier", "github.com/sergi/go-diff/diffmatchpatch", "github.com/shibumi/go-pathspec", "github.com/sigstore/cosign/v3/pkg/blob", "github.com/sigstore/cosign/v3/pkg/cosign", "github.com/sigstore/cosign/v3/pkg/cosign/attestation", "github.com/sigstore/cosign/v3/pkg/cosign/bundle", "github.com/sigstore/cosign/v3/pkg/cosign/env", "github.com/sigstore/cosign/v3/pkg/cosign/fulcioverifier/ctutil", "github.com/sigstore/cosign/v3/pkg/oci", "github.com/sigstore/cosign/v3/pkg/oci/empty", "github.com/sigstore/cosign/v3/pkg/oci/layout", "github.com/sigstore/cosign/v3/pkg/oci/remote", "github.com/sigstore/cosign/v3/pkg/oci/signed", "github.com/sigstore/cosign/v3/pkg/oci/static", "github.com/sigstore/cosign/v3/pkg/types", "github.com/sigstore/protobuf-specs/gen/pb-go/bundle/v1", "github.com/sigstore/protobuf-specs/gen/pb-go/common/v1", "github.com/sigstore/protobuf-specs/gen/pb-go/dsse", "github.com/sigstore/protobuf-specs/gen/pb-go/rekor/v1", "github.com/sigstore/protobuf-specs/gen/pb-go/trustroot/v1", "github.com/sigstore/rekor-tiles/v2/pkg/client", "github.com/sigstore/rekor-tiles/v2/pkg/client/write", "github.com/sigstore/rekor-tiles/v2/pkg/generated/protobuf", "github.com/sigstore/rekor-tiles/v2/pkg/note", "github.com/sigstore/rekor-tiles/v2/pkg/types/verifier", "github.com/sigstore/rekor-tiles/v2/pkg/verify", "github.com/sigstore/rekor/pkg/client", "github.com/sigstore/rekor/pkg/generated/client", "github.com/sigstore/rekor/pkg/generated/client/entries", "github.com/sigstore/rekor/pkg/generated/client/index", "github.com/sigstore/rekor/pkg/generated/client/pubkey", "github.com/sigstore/rekor/pkg/generated/client/tlog", "github.com/sigstore/rekor/pkg/generated/models", "github.com/sigstore/rekor/pkg/log", "github.com/sigstore/rekor/pkg/pki", "github.com/sigstore/rekor/pkg/pki/identity", "github.com/sigstore/rekor/pkg/pki/minisign", "github.com/sigstore/rekor/pkg/pki/pgp", "github.com/sigstore/rekor/pkg/pki/pkcs7", "github.com/sigstore/rekor/pkg/pki/pkitypes", "github.com/sigstore/rekor/pkg/pki/ssh", "github.com/sigstore/rekor/pkg/pki/tuf", "github.com/sigstore/rekor/pkg/pki/x509", "github.com/sigstore/rekor/pkg/tle", "github.com/sigstore/rekor/pkg/types", "github.com/sigstore/rekor/pkg/types/dsse", "github.com/sigstore/rekor/pkg/types/dsse/v0.0.1", "github.com/sigstore/rekor/pkg/types/hashedrekord", "github.com/sigstore/rekor/pkg/types/hashedrekord/v0.0.1", "github.com/sigstore/rekor/pkg/types/intoto", "github.com/sigstore/rekor/pkg/types/intoto/v0.0.1", "github.com/sigstore/rekor/pkg/types/intoto/v0.0.2", "github.com/sigstore/rekor/pkg/types/rekord", "github.com/sigstore/rekor/pkg/types/rekord/v0.0.1", "github.com/sigstore/rekor/pkg/util", "github.com/sigstore/rekor/pkg/verify", "github.com/sigstore/sigstore-go/pkg/bundle", "github.com/sigstore/sigstore-go/pkg/fulcio/certificate", "github.com/sigstore/sigstore-go/pkg/root", "github.com/sigstore/sigstore-go/pkg/sign", "github.com/sigstore/sigstore-go/pkg/tlog", "github.com/sigstore/sigstore-go/pkg/tuf", "github.com/sigstore/sigstore-go/pkg/util", "github.com/sigstore/sigstore-go/pkg/verify", "github.com/sigstore/sigstore/pkg/cryptoutils", "github.com/sigstore/sigstore/pkg/cryptoutils/goodkey", "github.com/sigstore/sigstore/pkg/fulcioroots", "github.com/sigstore/sigstore/pkg/oauth", "github.com/sigstore/sigstore/pkg/oauthflow", "github.com/sigstore/sigstore/pkg/signature", "github.com/sigstore/sigstore/pkg/signature/dsse", "github.com/sigstore/sigstore/pkg/signature/options", "github.com/sigstore/sigstore/pkg/signature/payload", "github.com/sigstore/sigstore/pkg/tuf", "github.com/sigstore/timestamp-authority/v2/pkg/verification", "github.com/sirupsen/logrus", "github.com/skeema/knownhosts", "github.com/spf13/afero", "github.com/spf13/afero/mem", "github.com/spf13/cobra", "github.com/spf13/pflag", "github.com/syndtr/goleveldb/leveldb", "github.com/syndtr/goleveldb/leveldb/cache", "github.com/syndtr/goleveldb/leveldb/comparer", "github.com/syndtr/goleveldb/leveldb/errors", "github.com/syndtr/goleveldb/leveldb/filter", "github.com/syndtr/goleveldb/leveldb/iterator", "github.com/syndtr/goleveldb/leveldb/journal", "github.com/syndtr/goleveldb/leveldb/memdb", "github.com/syndtr/goleveldb/leveldb/opt", "github.com/syndtr/goleveldb/leveldb/storage", "github.com/syndtr/goleveldb/leveldb/table", "github.com/syndtr/goleveldb/leveldb/util", "github.com/theupdateframework/go-tuf", "github.com/theupdateframework/go-tuf/client", "github.com/theupdateframework/go-tuf/client/leveldbstore", "github.com/theupdateframework/go-tuf/data", "github.com/theupdateframework/go-tuf/pkg/keys", "github.com/theupdateframework/go-tuf/pkg/targets", "github.com/theupdateframework/go-tuf/sign", "github.com/theupdateframework/go-tuf/util", "github.com/theupdateframework/go-tuf/v2/metadata", "github.com/theupdateframework/go-tuf/v2/metadata/config", "github.com/theupdateframework/go-tuf/v2/metadata/fetcher", "github.com/theupdateframework/go-tuf/v2/metadata/trustedmetadata", "github.com/theupdateframework/go-tuf/v2/metadata/updater", "github.com/theupdateframework/go-tuf/verify", "github.com/titanous/rocacheck", "github.com/transparency-dev/formats/log", "github.com/transparency-dev/merkle", "github.com/transparency-dev/merkle/compact", "github.com/transparency-dev/merkle/proof", "github.com/transparency-dev/merkle/rfc6962", "github.com/vbatts/tar-split/archive/tar", "github.com/willabides/kongplete", "github.com/x448/float16", "github.com/xanzy/ssh-agent", "github.com/xo/terminfo", "go.opentelemetry.io/auto/sdk", "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp", "go.opentelemetry.io/otel", "go.opentelemetry.io/otel/attribute", "go.opentelemetry.io/otel/baggage", "go.opentelemetry.io/otel/codes", "go.opentelemetry.io/otel/metric", "go.opentelemetry.io/otel/metric/embedded", "go.opentelemetry.io/otel/metric/noop", "go.opentelemetry.io/otel/propagation", "go.opentelemetry.io/otel/semconv/v1.37.0", "go.opentelemetry.io/otel/semconv/v1.40.0", "go.opentelemetry.io/otel/semconv/v1.40.0/httpconv", "go.opentelemetry.io/otel/trace", "go.opentelemetry.io/otel/trace/embedded", "go.opentelemetry.io/otel/trace/noop", "go.uber.org/multierr", "go.uber.org/zap", "go.uber.org/zap/buffer", "go.uber.org/zap/zapcore", "go.yaml.in/yaml/v2", "go.yaml.in/yaml/v3", "golang.org/x/crypto/argon2", "golang.org/x/crypto/blake2b", "golang.org/x/crypto/blowfish", "golang.org/x/crypto/cast5", "golang.org/x/crypto/chacha20", "golang.org/x/crypto/cryptobyte", "golang.org/x/crypto/cryptobyte/asn1", "golang.org/x/crypto/curve25519", "golang.org/x/crypto/ed25519", "golang.org/x/crypto/hkdf", "golang.org/x/crypto/nacl/secretbox", "golang.org/x/crypto/ocsp", "golang.org/x/crypto/openpgp", "golang.org/x/crypto/openpgp/armor", "golang.org/x/crypto/openpgp/elgamal", "golang.org/x/crypto/openpgp/errors", "golang.org/x/crypto/openpgp/packet", "golang.org/x/crypto/openpgp/s2k", "golang.org/x/crypto/pbkdf2", "golang.org/x/crypto/pkcs12", "golang.org/x/crypto/salsa20/salsa", "golang.org/x/crypto/scrypt", "golang.org/x/crypto/sha3", "golang.org/x/crypto/ssh", "golang.org/x/crypto/ssh/agent", "golang.org/x/crypto/ssh/knownhosts", "golang.org/x/crypto/ssh/terminal", "golang.org/x/exp/slices", "golang.org/x/mod/semver", "golang.org/x/mod/sumdb/note", "golang.org/x/net/context", "golang.org/x/net/http/httpguts", "golang.org/x/net/http2", "golang.org/x/net/http2/hpack", "golang.org/x/net/idna", "golang.org/x/net/proxy", "golang.org/x/net/trace", "golang.org/x/oauth2", "golang.org/x/oauth2/authhandler", "golang.org/x/oauth2/google", "golang.org/x/oauth2/google/externalaccount", "golang.org/x/oauth2/jws", "golang.org/x/oauth2/jwt", "golang.org/x/sync/errgroup", "golang.org/x/sync/singleflight", "golang.org/x/sys/cpu", "golang.org/x/sys/execabs", "golang.org/x/sys/unix", "golang.org/x/term", "golang.org/x/text/feature/plural", "golang.org/x/text/language", "golang.org/x/text/message", "golang.org/x/text/message/catalog", "golang.org/x/text/runes", "golang.org/x/text/secure/bidirule", "golang.org/x/text/transform", "golang.org/x/text/unicode/bidi", "golang.org/x/text/unicode/norm", "golang.org/x/time/rate", "gomodules.xyz/jsonpatch/v2", "google.golang.org/genproto/googleapis/api", "google.golang.org/genproto/googleapis/api/annotations", "google.golang.org/genproto/googleapis/api/expr/v1alpha1", "google.golang.org/genproto/googleapis/api/httpbody", "google.golang.org/genproto/googleapis/rpc/status", "google.golang.org/grpc", "google.golang.org/grpc/attributes", "google.golang.org/grpc/backoff", "google.golang.org/grpc/balancer", "google.golang.org/grpc/balancer/base", "google.golang.org/grpc/balancer/endpointsharding", "google.golang.org/grpc/balancer/grpclb/state", "google.golang.org/grpc/balancer/pickfirst", "google.golang.org/grpc/balancer/roundrobin", "google.golang.org/grpc/binarylog/grpc_binarylog_v1", "google.golang.org/grpc/channelz", "google.golang.org/grpc/codes", "google.golang.org/grpc/connectivity", "google.golang.org/grpc/credentials", "google.golang.org/grpc/credentials/insecure", "google.golang.org/grpc/encoding", "google.golang.org/grpc/encoding/proto", "google.golang.org/grpc/experimental/stats", "google.golang.org/grpc/grpclog", "google.golang.org/grpc/health/grpc_health_v1", "google.golang.org/grpc/keepalive", "google.golang.org/grpc/mem", "google.golang.org/grpc/metadata", "google.golang.org/grpc/peer", "google.golang.org/grpc/resolver", "google.golang.org/grpc/resolver/dns", "google.golang.org/grpc/serviceconfig", "google.golang.org/grpc/stats", "google.golang.org/grpc/status", "google.golang.org/grpc/tap", "google.golang.org/protobuf/encoding/protodelim", "google.golang.org/protobuf/encoding/protojson", "google.golang.org/protobuf/encoding/prototext", "google.golang.org/protobuf/encoding/protowire", "google.golang.org/protobuf/proto", "google.golang.org/protobuf/protoadapt", "google.golang.org/protobuf/reflect/protodesc", "google.golang.org/protobuf/reflect/protoreflect", "google.golang.org/protobuf/reflect/protoregistry", "google.golang.org/protobuf/runtime/protoiface", "google.golang.org/protobuf/runtime/protoimpl", "google.golang.org/protobuf/testing/protocmp", "google.golang.org/protobuf/types/descriptorpb", "google.golang.org/protobuf/types/dynamicpb", "google.golang.org/protobuf/types/gofeaturespb", "google.golang.org/protobuf/types/known/anypb", "google.golang.org/protobuf/types/known/durationpb", "google.golang.org/protobuf/types/known/emptypb", "google.golang.org/protobuf/types/known/fieldmaskpb", "google.golang.org/protobuf/types/known/structpb", "google.golang.org/protobuf/types/known/timestamppb", "google.golang.org/protobuf/types/known/wrapperspb", "gopkg.in/evanphx/json-patch.v4", "gopkg.in/inf.v0", "gopkg.in/warnings.v0", "gopkg.in/yaml.v3", "k8s.io/api/admission/v1", "k8s.io/api/admission/v1beta1", "k8s.io/api/admissionregistration/v1", "k8s.io/api/admissionregistration/v1alpha1", "k8s.io/api/admissionregistration/v1beta1", "k8s.io/api/apidiscovery/v2", "k8s.io/api/apidiscovery/v2beta1", "k8s.io/api/apiserverinternal/v1alpha1", "k8s.io/api/apps/v1", "k8s.io/api/apps/v1beta1", "k8s.io/api/apps/v1beta2", "k8s.io/api/authentication/v1", "k8s.io/api/authentication/v1alpha1", "k8s.io/api/authentication/v1beta1", "k8s.io/api/authorization/v1", "k8s.io/api/authorization/v1beta1", "k8s.io/api/autoscaling/v1", "k8s.io/api/autoscaling/v2", "k8s.io/api/autoscaling/v2beta1", "k8s.io/api/autoscaling/v2beta2", "k8s.io/api/batch/v1", "k8s.io/api/batch/v1beta1", "k8s.io/api/certificates/v1", "k8s.io/api/certificates/v1alpha1", "k8s.io/api/certificates/v1beta1", "k8s.io/api/coordination/v1", "k8s.io/api/coordination/v1alpha2", "k8s.io/api/coordination/v1beta1", "k8s.io/api/core/v1", "k8s.io/api/discovery/v1", "k8s.io/api/discovery/v1beta1", "k8s.io/api/events/v1", "k8s.io/api/events/v1beta1", "k8s.io/api/extensions/v1beta1", "k8s.io/api/flowcontrol/v1", "k8s.io/api/flowcontrol/v1beta1", "k8s.io/api/flowcontrol/v1beta2", "k8s.io/api/flowcontrol/v1beta3", "k8s.io/api/networking/v1", "k8s.io/api/networking/v1beta1", "k8s.io/api/node/v1", "k8s.io/api/node/v1alpha1", "k8s.io/api/node/v1beta1", "k8s.io/api/policy/v1", "k8s.io/api/policy/v1beta1", "k8s.io/api/rbac/v1", "k8s.io/api/rbac/v1alpha1", "k8s.io/api/rbac/v1beta1", "k8s.io/api/resource/v1", "k8s.io/api/resource/v1alpha3", "k8s.io/api/resource/v1beta1", "k8s.io/api/resource/v1beta2", "k8s.io/api/scheduling/v1", "k8s.io/api/scheduling/v1alpha1", "k8s.io/api/scheduling/v1beta1", "k8s.io/api/storage/v1", "k8s.io/api/storage/v1alpha1", "k8s.io/api/storage/v1beta1", "k8s.io/api/storagemigration/v1beta1", "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions", "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1", "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1", "k8s.io/apiextensions-apiserver/pkg/apiserver/schema", "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel", "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model", "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/defaulting", "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/objectmeta", "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/pruning", "k8s.io/apiextensions-apiserver/pkg/apiserver/validation", "k8s.io/apiextensions-apiserver/pkg/features", "k8s.io/apimachinery/pkg/api/equality", "k8s.io/apimachinery/pkg/api/errors", "k8s.io/apimachinery/pkg/api/meta", "k8s.io/apimachinery/pkg/api/meta/testrestmapper", "k8s.io/apimachinery/pkg/api/operation", "k8s.io/apimachinery/pkg/api/resource", "k8s.io/apimachinery/pkg/api/safe", "k8s.io/apimachinery/pkg/api/validate", "k8s.io/apimachinery/pkg/api/validate/constraints", "k8s.io/apimachinery/pkg/api/validate/content", "k8s.io/apimachinery/pkg/api/validation", "k8s.io/apimachinery/pkg/api/validation/path", "k8s.io/apimachinery/pkg/apis/meta/v1", "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured", "k8s.io/apimachinery/pkg/apis/meta/v1/validation", "k8s.io/apimachinery/pkg/apis/meta/v1beta1", "k8s.io/apimachinery/pkg/conversion", "k8s.io/apimachinery/pkg/conversion/queryparams", "k8s.io/apimachinery/pkg/fields", "k8s.io/apimachinery/pkg/labels", "k8s.io/apimachinery/pkg/runtime", "k8s.io/apimachinery/pkg/runtime/schema", "k8s.io/apimachinery/pkg/runtime/serializer", "k8s.io/apimachinery/pkg/runtime/serializer/cbor", "k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct", "k8s.io/apimachinery/pkg/runtime/serializer/json", "k8s.io/apimachinery/pkg/runtime/serializer/protobuf", "k8s.io/apimachinery/pkg/runtime/serializer/recognizer", "k8s.io/apimachinery/pkg/runtime/serializer/streaming", "k8s.io/apimachinery/pkg/runtime/serializer/versioning", "k8s.io/apimachinery/pkg/selection", "k8s.io/apimachinery/pkg/types", "k8s.io/apimachinery/pkg/util/cache", "k8s.io/apimachinery/pkg/util/diff", "k8s.io/apimachinery/pkg/util/dump", "k8s.io/apimachinery/pkg/util/duration", "k8s.io/apimachinery/pkg/util/errors", "k8s.io/apimachinery/pkg/util/framer", "k8s.io/apimachinery/pkg/util/intstr", "k8s.io/apimachinery/pkg/util/json", "k8s.io/apimachinery/pkg/util/managedfields", "k8s.io/apimachinery/pkg/util/mergepatch", "k8s.io/apimachinery/pkg/util/naming", "k8s.io/apimachinery/pkg/util/net", "k8s.io/apimachinery/pkg/util/rand", "k8s.io/apimachinery/pkg/util/runtime", "k8s.io/apimachinery/pkg/util/sets", "k8s.io/apimachinery/pkg/util/strategicpatch", "k8s.io/apimachinery/pkg/util/uuid", "k8s.io/apimachinery/pkg/util/validation", "k8s.io/apimachinery/pkg/util/validation/field", "k8s.io/apimachinery/pkg/util/version", "k8s.io/apimachinery/pkg/util/wait", "k8s.io/apimachinery/pkg/util/yaml", "k8s.io/apimachinery/pkg/version", "k8s.io/apimachinery/pkg/watch", "k8s.io/apimachinery/third_party/forked/golang/json", "k8s.io/apimachinery/third_party/forked/golang/reflect", "k8s.io/apiserver/pkg/apis/cel", "k8s.io/apiserver/pkg/authentication/serviceaccount", "k8s.io/apiserver/pkg/authentication/user", "k8s.io/apiserver/pkg/authorization/authorizer", "k8s.io/apiserver/pkg/cel", "k8s.io/apiserver/pkg/cel/common", "k8s.io/apiserver/pkg/cel/environment", "k8s.io/apiserver/pkg/cel/library", "k8s.io/apiserver/pkg/cel/metrics", "k8s.io/apiserver/pkg/cel/openapi", "k8s.io/apiserver/pkg/features", "k8s.io/apiserver/pkg/util/compatibility", "k8s.io/apiserver/pkg/util/feature", "k8s.io/apiserver/pkg/warning", "k8s.io/cli-runtime/pkg/printers", "k8s.io/client-go/applyconfigurations/admissionregistration/v1", "k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1", "k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1", "k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1", "k8s.io/client-go/applyconfigurations/apps/v1", "k8s.io/client-go/applyconfigurations/apps/v1beta1", "k8s.io/client-go/applyconfigurations/apps/v1beta2", "k8s.io/client-go/applyconfigurations/autoscaling/v1", "k8s.io/client-go/applyconfigurations/autoscaling/v2", "k8s.io/client-go/applyconfigurations/autoscaling/v2beta1", "k8s.io/client-go/applyconfigurations/autoscaling/v2beta2", "k8s.io/client-go/applyconfigurations/batch/v1", "k8s.io/client-go/applyconfigurations/batch/v1beta1", "k8s.io/client-go/applyconfigurations/certificates/v1", "k8s.io/client-go/applyconfigurations/certificates/v1alpha1", "k8s.io/client-go/applyconfigurations/certificates/v1beta1", "k8s.io/client-go/applyconfigurations/coordination/v1", "k8s.io/client-go/applyconfigurations/coordination/v1alpha2", "k8s.io/client-go/applyconfigurations/coordination/v1beta1", "k8s.io/client-go/applyconfigurations/core/v1", "k8s.io/client-go/applyconfigurations/discovery/v1", "k8s.io/client-go/applyconfigurations/discovery/v1beta1", "k8s.io/client-go/applyconfigurations/events/v1", "k8s.io/client-go/applyconfigurations/events/v1beta1", "k8s.io/client-go/applyconfigurations/extensions/v1beta1", "k8s.io/client-go/applyconfigurations/flowcontrol/v1", "k8s.io/client-go/applyconfigurations/flowcontrol/v1beta1", "k8s.io/client-go/applyconfigurations/flowcontrol/v1beta2", "k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3", "k8s.io/client-go/applyconfigurations/meta/v1", "k8s.io/client-go/applyconfigurations/networking/v1", "k8s.io/client-go/applyconfigurations/networking/v1beta1", "k8s.io/client-go/applyconfigurations/node/v1", "k8s.io/client-go/applyconfigurations/node/v1alpha1", "k8s.io/client-go/applyconfigurations/node/v1beta1", "k8s.io/client-go/applyconfigurations/policy/v1", "k8s.io/client-go/applyconfigurations/policy/v1beta1", "k8s.io/client-go/applyconfigurations/rbac/v1", "k8s.io/client-go/applyconfigurations/rbac/v1alpha1", "k8s.io/client-go/applyconfigurations/rbac/v1beta1", "k8s.io/client-go/applyconfigurations/resource/v1", "k8s.io/client-go/applyconfigurations/resource/v1alpha3", "k8s.io/client-go/applyconfigurations/resource/v1beta1", "k8s.io/client-go/applyconfigurations/resource/v1beta2", "k8s.io/client-go/applyconfigurations/scheduling/v1", "k8s.io/client-go/applyconfigurations/scheduling/v1alpha1", "k8s.io/client-go/applyconfigurations/scheduling/v1beta1", "k8s.io/client-go/applyconfigurations/storage/v1", "k8s.io/client-go/applyconfigurations/storage/v1alpha1", "k8s.io/client-go/applyconfigurations/storage/v1beta1", "k8s.io/client-go/applyconfigurations/storagemigration/v1beta1", "k8s.io/client-go/discovery", "k8s.io/client-go/discovery/cached/memory", "k8s.io/client-go/dynamic", "k8s.io/client-go/features", "k8s.io/client-go/gentype", "k8s.io/client-go/informers", "k8s.io/client-go/informers/admissionregistration", "k8s.io/client-go/informers/admissionregistration/v1", "k8s.io/client-go/informers/admissionregistration/v1alpha1", "k8s.io/client-go/informers/admissionregistration/v1beta1", "k8s.io/client-go/informers/apiserverinternal", "k8s.io/client-go/informers/apiserverinternal/v1alpha1", "k8s.io/client-go/informers/apps", "k8s.io/client-go/informers/apps/v1", "k8s.io/client-go/informers/apps/v1beta1", "k8s.io/client-go/informers/apps/v1beta2", "k8s.io/client-go/informers/autoscaling", "k8s.io/client-go/informers/autoscaling/v1", "k8s.io/client-go/informers/autoscaling/v2", "k8s.io/client-go/informers/autoscaling/v2beta1", "k8s.io/client-go/informers/autoscaling/v2beta2", "k8s.io/client-go/informers/batch", "k8s.io/client-go/informers/batch/v1", "k8s.io/client-go/informers/batch/v1beta1", "k8s.io/client-go/informers/certificates", "k8s.io/client-go/informers/certificates/v1", "k8s.io/client-go/informers/certificates/v1alpha1", "k8s.io/client-go/informers/certificates/v1beta1", "k8s.io/client-go/informers/coordination", "k8s.io/client-go/informers/coordination/v1", "k8s.io/client-go/informers/coordination/v1alpha2", "k8s.io/client-go/informers/coordination/v1beta1", "k8s.io/client-go/informers/core", "k8s.io/client-go/informers/core/v1", "k8s.io/client-go/informers/discovery", "k8s.io/client-go/informers/discovery/v1", "k8s.io/client-go/informers/discovery/v1beta1", "k8s.io/client-go/informers/events", "k8s.io/client-go/informers/events/v1", "k8s.io/client-go/informers/events/v1beta1", "k8s.io/client-go/informers/extensions", "k8s.io/client-go/informers/extensions/v1beta1", "k8s.io/client-go/informers/flowcontrol", "k8s.io/client-go/informers/flowcontrol/v1", "k8s.io/client-go/informers/flowcontrol/v1beta1", "k8s.io/client-go/informers/flowcontrol/v1beta2", "k8s.io/client-go/informers/flowcontrol/v1beta3", "k8s.io/client-go/informers/networking", "k8s.io/client-go/informers/networking/v1", "k8s.io/client-go/informers/networking/v1beta1", "k8s.io/client-go/informers/node", "k8s.io/client-go/informers/node/v1", "k8s.io/client-go/informers/node/v1alpha1", "k8s.io/client-go/informers/node/v1beta1", "k8s.io/client-go/informers/policy", "k8s.io/client-go/informers/policy/v1", "k8s.io/client-go/informers/policy/v1beta1", "k8s.io/client-go/informers/rbac", "k8s.io/client-go/informers/rbac/v1", "k8s.io/client-go/informers/rbac/v1alpha1", "k8s.io/client-go/informers/rbac/v1beta1", "k8s.io/client-go/informers/resource", "k8s.io/client-go/informers/resource/v1", "k8s.io/client-go/informers/resource/v1alpha3", "k8s.io/client-go/informers/resource/v1beta1", "k8s.io/client-go/informers/resource/v1beta2", "k8s.io/client-go/informers/scheduling", "k8s.io/client-go/informers/scheduling/v1", "k8s.io/client-go/informers/scheduling/v1alpha1", "k8s.io/client-go/informers/scheduling/v1beta1", "k8s.io/client-go/informers/storage", "k8s.io/client-go/informers/storage/v1", "k8s.io/client-go/informers/storage/v1alpha1", "k8s.io/client-go/informers/storage/v1beta1", "k8s.io/client-go/informers/storagemigration", "k8s.io/client-go/informers/storagemigration/v1beta1", "k8s.io/client-go/kubernetes", "k8s.io/client-go/kubernetes/scheme", "k8s.io/client-go/kubernetes/typed/admissionregistration/v1", "k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1", "k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1", "k8s.io/client-go/kubernetes/typed/apiserverinternal/v1alpha1", "k8s.io/client-go/kubernetes/typed/apps/v1", "k8s.io/client-go/kubernetes/typed/apps/v1beta1", "k8s.io/client-go/kubernetes/typed/apps/v1beta2", "k8s.io/client-go/kubernetes/typed/authentication/v1", "k8s.io/client-go/kubernetes/typed/authentication/v1alpha1", "k8s.io/client-go/kubernetes/typed/authentication/v1beta1", "k8s.io/client-go/kubernetes/typed/authorization/v1", "k8s.io/client-go/kubernetes/typed/authorization/v1beta1", "k8s.io/client-go/kubernetes/typed/autoscaling/v1", "k8s.io/client-go/kubernetes/typed/autoscaling/v2", "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1", "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2", "k8s.io/client-go/kubernetes/typed/batch/v1", "k8s.io/client-go/kubernetes/typed/batch/v1beta1", "k8s.io/client-go/kubernetes/typed/certificates/v1", "k8s.io/client-go/kubernetes/typed/certificates/v1alpha1", "k8s.io/client-go/kubernetes/typed/certificates/v1beta1", "k8s.io/client-go/kubernetes/typed/coordination/v1", "k8s.io/client-go/kubernetes/typed/coordination/v1alpha2", "k8s.io/client-go/kubernetes/typed/coordination/v1beta1", "k8s.io/client-go/kubernetes/typed/core/v1", "k8s.io/client-go/kubernetes/typed/discovery/v1", "k8s.io/client-go/kubernetes/typed/discovery/v1beta1", "k8s.io/client-go/kubernetes/typed/events/v1", "k8s.io/client-go/kubernetes/typed/events/v1beta1", "k8s.io/client-go/kubernetes/typed/extensions/v1beta1", "k8s.io/client-go/kubernetes/typed/flowcontrol/v1", "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1", "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta2", "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3", "k8s.io/client-go/kubernetes/typed/networking/v1", "k8s.io/client-go/kubernetes/typed/networking/v1beta1", "k8s.io/client-go/kubernetes/typed/node/v1", "k8s.io/client-go/kubernetes/typed/node/v1alpha1", "k8s.io/client-go/kubernetes/typed/node/v1beta1", "k8s.io/client-go/kubernetes/typed/policy/v1", "k8s.io/client-go/kubernetes/typed/policy/v1beta1", "k8s.io/client-go/kubernetes/typed/rbac/v1", "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1", "k8s.io/client-go/kubernetes/typed/rbac/v1beta1", "k8s.io/client-go/kubernetes/typed/resource/v1", "k8s.io/client-go/kubernetes/typed/resource/v1alpha3", "k8s.io/client-go/kubernetes/typed/resource/v1beta1", "k8s.io/client-go/kubernetes/typed/resource/v1beta2", "k8s.io/client-go/kubernetes/typed/scheduling/v1", "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1", "k8s.io/client-go/kubernetes/typed/scheduling/v1beta1", "k8s.io/client-go/kubernetes/typed/storage/v1", "k8s.io/client-go/kubernetes/typed/storage/v1alpha1", "k8s.io/client-go/kubernetes/typed/storage/v1beta1", "k8s.io/client-go/kubernetes/typed/storagemigration/v1beta1", "k8s.io/client-go/listers", "k8s.io/client-go/listers/admissionregistration/v1", "k8s.io/client-go/listers/admissionregistration/v1alpha1", "k8s.io/client-go/listers/admissionregistration/v1beta1", "k8s.io/client-go/listers/apiserverinternal/v1alpha1", "k8s.io/client-go/listers/apps/v1", "k8s.io/client-go/listers/apps/v1beta1", "k8s.io/client-go/listers/apps/v1beta2", "k8s.io/client-go/listers/autoscaling/v1", "k8s.io/client-go/listers/autoscaling/v2", "k8s.io/client-go/listers/autoscaling/v2beta1", "k8s.io/client-go/listers/autoscaling/v2beta2", "k8s.io/client-go/listers/batch/v1", "k8s.io/client-go/listers/batch/v1beta1", "k8s.io/client-go/listers/certificates/v1", "k8s.io/client-go/listers/certificates/v1alpha1", "k8s.io/client-go/listers/certificates/v1beta1", "k8s.io/client-go/listers/coordination/v1", "k8s.io/client-go/listers/coordination/v1alpha2", "k8s.io/client-go/listers/coordination/v1beta1", "k8s.io/client-go/listers/core/v1", "k8s.io/client-go/listers/discovery/v1", "k8s.io/client-go/listers/discovery/v1beta1", "k8s.io/client-go/listers/events/v1", "k8s.io/client-go/listers/events/v1beta1", "k8s.io/client-go/listers/extensions/v1beta1", "k8s.io/client-go/listers/flowcontrol/v1", "k8s.io/client-go/listers/flowcontrol/v1beta1", "k8s.io/client-go/listers/flowcontrol/v1beta2", "k8s.io/client-go/listers/flowcontrol/v1beta3", "k8s.io/client-go/listers/networking/v1", "k8s.io/client-go/listers/networking/v1beta1", "k8s.io/client-go/listers/node/v1", "k8s.io/client-go/listers/node/v1alpha1", "k8s.io/client-go/listers/node/v1beta1", "k8s.io/client-go/listers/policy/v1", "k8s.io/client-go/listers/policy/v1beta1", "k8s.io/client-go/listers/rbac/v1", "k8s.io/client-go/listers/rbac/v1alpha1", "k8s.io/client-go/listers/rbac/v1beta1", "k8s.io/client-go/listers/resource/v1", "k8s.io/client-go/listers/resource/v1alpha3", "k8s.io/client-go/listers/resource/v1beta1", "k8s.io/client-go/listers/resource/v1beta2", "k8s.io/client-go/listers/scheduling/v1", "k8s.io/client-go/listers/scheduling/v1alpha1", "k8s.io/client-go/listers/scheduling/v1beta1", "k8s.io/client-go/listers/storage/v1", "k8s.io/client-go/listers/storage/v1alpha1", "k8s.io/client-go/listers/storage/v1beta1", "k8s.io/client-go/listers/storagemigration/v1beta1", "k8s.io/client-go/metadata", "k8s.io/client-go/openapi", "k8s.io/client-go/openapi/cached", "k8s.io/client-go/pkg/apis/clientauthentication", "k8s.io/client-go/pkg/apis/clientauthentication/install", "k8s.io/client-go/pkg/apis/clientauthentication/v1", "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1", "k8s.io/client-go/pkg/version", "k8s.io/client-go/plugin/pkg/client/auth", "k8s.io/client-go/plugin/pkg/client/auth/azure", "k8s.io/client-go/plugin/pkg/client/auth/exec", "k8s.io/client-go/plugin/pkg/client/auth/gcp", "k8s.io/client-go/plugin/pkg/client/auth/oidc", "k8s.io/client-go/rest", "k8s.io/client-go/rest/watch", "k8s.io/client-go/restmapper", "k8s.io/client-go/testing", "k8s.io/client-go/third_party/forked/golang/template", "k8s.io/client-go/tools/auth", "k8s.io/client-go/tools/cache", "k8s.io/client-go/tools/cache/synctrack", "k8s.io/client-go/tools/clientcmd", "k8s.io/client-go/tools/clientcmd/api", "k8s.io/client-go/tools/clientcmd/api/latest", "k8s.io/client-go/tools/clientcmd/api/v1", "k8s.io/client-go/tools/events", "k8s.io/client-go/tools/leaderelection", "k8s.io/client-go/tools/leaderelection/resourcelock", "k8s.io/client-go/tools/metrics", "k8s.io/client-go/tools/pager", "k8s.io/client-go/tools/record", "k8s.io/client-go/tools/record/util", "k8s.io/client-go/tools/reference", "k8s.io/client-go/transport", "k8s.io/client-go/util/apply", "k8s.io/client-go/util/cert", "k8s.io/client-go/util/connrotation", "k8s.io/client-go/util/consistencydetector", "k8s.io/client-go/util/flowcontrol", "k8s.io/client-go/util/homedir", "k8s.io/client-go/util/jsonpath", "k8s.io/client-go/util/keyutil", "k8s.io/client-go/util/retry", "k8s.io/client-go/util/watchlist", "k8s.io/client-go/util/workqueue", "k8s.io/component-base/cli/flag", "k8s.io/component-base/compatibility", "k8s.io/component-base/featuregate", "k8s.io/component-base/metrics", "k8s.io/component-base/metrics/legacyregistry", "k8s.io/component-base/metrics/prometheus/compatversion", "k8s.io/component-base/metrics/prometheus/feature", "k8s.io/component-base/metrics/prometheusextension", "k8s.io/component-base/version", "k8s.io/component-base/zpages/features", "k8s.io/klog/v2", "k8s.io/kube-openapi/pkg/cached", "k8s.io/kube-openapi/pkg/common", "k8s.io/kube-openapi/pkg/handler3", "k8s.io/kube-openapi/pkg/schemaconv", "k8s.io/kube-openapi/pkg/spec3", "k8s.io/kube-openapi/pkg/util", "k8s.io/kube-openapi/pkg/util/proto", "k8s.io/kube-openapi/pkg/validation/errors", "k8s.io/kube-openapi/pkg/validation/spec", "k8s.io/kube-openapi/pkg/validation/strfmt", "k8s.io/kube-openapi/pkg/validation/strfmt/bson", "k8s.io/kube-openapi/pkg/validation/validate", "k8s.io/metrics/pkg/apis/metrics", "k8s.io/metrics/pkg/apis/metrics/v1alpha1", "k8s.io/metrics/pkg/apis/metrics/v1beta1", "k8s.io/metrics/pkg/client/clientset/versioned", "k8s.io/metrics/pkg/client/clientset/versioned/scheme", "k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1alpha1", "k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1beta1", "k8s.io/utils/buffer", "k8s.io/utils/clock", "k8s.io/utils/lru", "k8s.io/utils/net", "k8s.io/utils/ptr", "k8s.io/utils/trace", "sigs.k8s.io/controller-runtime", "sigs.k8s.io/controller-runtime/pkg/builder", "sigs.k8s.io/controller-runtime/pkg/cache", "sigs.k8s.io/controller-runtime/pkg/certwatcher", "sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics", "sigs.k8s.io/controller-runtime/pkg/client", "sigs.k8s.io/controller-runtime/pkg/client/apiutil", "sigs.k8s.io/controller-runtime/pkg/client/config", "sigs.k8s.io/controller-runtime/pkg/cluster", "sigs.k8s.io/controller-runtime/pkg/config", "sigs.k8s.io/controller-runtime/pkg/controller", "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil", "sigs.k8s.io/controller-runtime/pkg/controller/priorityqueue", "sigs.k8s.io/controller-runtime/pkg/conversion", "sigs.k8s.io/controller-runtime/pkg/event", "sigs.k8s.io/controller-runtime/pkg/handler", "sigs.k8s.io/controller-runtime/pkg/healthz", "sigs.k8s.io/controller-runtime/pkg/leaderelection", "sigs.k8s.io/controller-runtime/pkg/log", "sigs.k8s.io/controller-runtime/pkg/log/zap", "sigs.k8s.io/controller-runtime/pkg/manager", "sigs.k8s.io/controller-runtime/pkg/manager/signals", "sigs.k8s.io/controller-runtime/pkg/metrics", "sigs.k8s.io/controller-runtime/pkg/metrics/server", "sigs.k8s.io/controller-runtime/pkg/predicate", "sigs.k8s.io/controller-runtime/pkg/reconcile", "sigs.k8s.io/controller-runtime/pkg/recorder", "sigs.k8s.io/controller-runtime/pkg/scheme", "sigs.k8s.io/controller-runtime/pkg/source", "sigs.k8s.io/controller-runtime/pkg/webhook", "sigs.k8s.io/controller-runtime/pkg/webhook/admission", "sigs.k8s.io/controller-runtime/pkg/webhook/admission/metrics", "sigs.k8s.io/controller-runtime/pkg/webhook/conversion", "sigs.k8s.io/controller-runtime/pkg/webhook/conversion/metrics", "sigs.k8s.io/json", "sigs.k8s.io/randfill", "sigs.k8s.io/randfill/bytesource", "sigs.k8s.io/structured-merge-diff/v6/fieldpath", "sigs.k8s.io/structured-merge-diff/v6/merge", "sigs.k8s.io/structured-merge-diff/v6/schema", "sigs.k8s.io/structured-merge-diff/v6/typed", "sigs.k8s.io/structured-merge-diff/v6/value", "sigs.k8s.io/yaml", "sigs.k8s.io/yaml/kyaml"] +cachePackages = ["cel.dev/expr", "cloud.google.com/go/compute/metadata", "dario.cat/mergo", "github.com/Azure/azure-sdk-for-go/services/preview/containerregistry/runtime/2019-08-15-preview/containerregistry", "github.com/Azure/azure-sdk-for-go/version", "github.com/Azure/go-autorest/autorest", "github.com/Azure/go-autorest/autorest/adal", "github.com/Azure/go-autorest/autorest/azure", "github.com/Azure/go-autorest/autorest/azure/auth", "github.com/Azure/go-autorest/autorest/azure/cli", "github.com/Azure/go-autorest/autorest/date", "github.com/Azure/go-autorest/logger", "github.com/Azure/go-autorest/tracing", "github.com/Masterminds/semver/v3", "github.com/ProtonMail/go-crypto/bitcurves", "github.com/ProtonMail/go-crypto/brainpool", "github.com/ProtonMail/go-crypto/eax", "github.com/ProtonMail/go-crypto/ocb", "github.com/ProtonMail/go-crypto/openpgp", "github.com/ProtonMail/go-crypto/openpgp/aes/keywrap", "github.com/ProtonMail/go-crypto/openpgp/armor", "github.com/ProtonMail/go-crypto/openpgp/ecdh", "github.com/ProtonMail/go-crypto/openpgp/ecdsa", "github.com/ProtonMail/go-crypto/openpgp/ed25519", "github.com/ProtonMail/go-crypto/openpgp/ed448", "github.com/ProtonMail/go-crypto/openpgp/eddsa", "github.com/ProtonMail/go-crypto/openpgp/elgamal", "github.com/ProtonMail/go-crypto/openpgp/errors", "github.com/ProtonMail/go-crypto/openpgp/packet", "github.com/ProtonMail/go-crypto/openpgp/s2k", "github.com/ProtonMail/go-crypto/openpgp/x25519", "github.com/ProtonMail/go-crypto/openpgp/x448", "github.com/alecthomas/chroma/v2", "github.com/alecthomas/chroma/v2/formatters", "github.com/alecthomas/chroma/v2/formatters/html", "github.com/alecthomas/chroma/v2/formatters/svg", "github.com/alecthomas/chroma/v2/lexers", "github.com/alecthomas/chroma/v2/quick", "github.com/alecthomas/chroma/v2/styles", "github.com/alecthomas/kong", "github.com/antlr4-go/antlr/v4", "github.com/asaskevich/govalidator", "github.com/aws/aws-sdk-go-v2/aws", "github.com/aws/aws-sdk-go-v2/aws/defaults", "github.com/aws/aws-sdk-go-v2/aws/middleware", "github.com/aws/aws-sdk-go-v2/aws/protocol/query", "github.com/aws/aws-sdk-go-v2/aws/protocol/restjson", "github.com/aws/aws-sdk-go-v2/aws/protocol/xml", "github.com/aws/aws-sdk-go-v2/aws/ratelimit", "github.com/aws/aws-sdk-go-v2/aws/retry", "github.com/aws/aws-sdk-go-v2/aws/signer/v4", "github.com/aws/aws-sdk-go-v2/aws/transport/http", "github.com/aws/aws-sdk-go-v2/config", "github.com/aws/aws-sdk-go-v2/credentials", "github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds", "github.com/aws/aws-sdk-go-v2/credentials/endpointcreds", "github.com/aws/aws-sdk-go-v2/credentials/logincreds", "github.com/aws/aws-sdk-go-v2/credentials/processcreds", "github.com/aws/aws-sdk-go-v2/credentials/ssocreds", "github.com/aws/aws-sdk-go-v2/credentials/stscreds", "github.com/aws/aws-sdk-go-v2/feature/ec2/imds", "github.com/aws/aws-sdk-go-v2/service/ecr", "github.com/aws/aws-sdk-go-v2/service/ecr/types", "github.com/aws/aws-sdk-go-v2/service/ecrpublic", "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types", "github.com/aws/aws-sdk-go-v2/service/signin", "github.com/aws/aws-sdk-go-v2/service/signin/types", "github.com/aws/aws-sdk-go-v2/service/sso", "github.com/aws/aws-sdk-go-v2/service/sso/types", "github.com/aws/aws-sdk-go-v2/service/ssooidc", "github.com/aws/aws-sdk-go-v2/service/ssooidc/types", "github.com/aws/aws-sdk-go-v2/service/sts", "github.com/aws/aws-sdk-go-v2/service/sts/types", "github.com/aws/smithy-go", "github.com/aws/smithy-go/auth", "github.com/aws/smithy-go/auth/bearer", "github.com/aws/smithy-go/context", "github.com/aws/smithy-go/document", "github.com/aws/smithy-go/encoding", "github.com/aws/smithy-go/encoding/httpbinding", "github.com/aws/smithy-go/encoding/json", "github.com/aws/smithy-go/encoding/xml", "github.com/aws/smithy-go/endpoints", "github.com/aws/smithy-go/endpoints/private/rulesfn", "github.com/aws/smithy-go/io", "github.com/aws/smithy-go/logging", "github.com/aws/smithy-go/metrics", "github.com/aws/smithy-go/middleware", "github.com/aws/smithy-go/private/requestcompression", "github.com/aws/smithy-go/ptr", "github.com/aws/smithy-go/rand", "github.com/aws/smithy-go/time", "github.com/aws/smithy-go/tracing", "github.com/aws/smithy-go/transport/http", "github.com/aws/smithy-go/waiter", "github.com/awslabs/amazon-ecr-credential-helper/ecr-login", "github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api", "github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cache", "github.com/awslabs/amazon-ecr-credential-helper/ecr-login/config", "github.com/awslabs/amazon-ecr-credential-helper/ecr-login/version", "github.com/aymanbagabas/go-osc52/v2", "github.com/aymerick/douceur/css", "github.com/aymerick/douceur/parser", "github.com/beorn7/perks/quantile", "github.com/blang/semver", "github.com/blang/semver/v4", "github.com/cenkalti/backoff/v5", "github.com/cespare/xxhash/v2", "github.com/charmbracelet/bubbletea", "github.com/charmbracelet/colorprofile", "github.com/charmbracelet/glamour", "github.com/charmbracelet/glamour/ansi", "github.com/charmbracelet/glamour/styles", "github.com/charmbracelet/lipgloss", "github.com/charmbracelet/lipgloss/table", "github.com/charmbracelet/x/ansi", "github.com/charmbracelet/x/ansi/parser", "github.com/charmbracelet/x/cellbuf", "github.com/charmbracelet/x/exp/slice", "github.com/charmbracelet/x/term", "github.com/chrismellard/docker-credential-acr-env/pkg/credhelper", "github.com/chrismellard/docker-credential-acr-env/pkg/registry", "github.com/chrismellard/docker-credential-acr-env/pkg/token", "github.com/clipperhouse/displaywidth", "github.com/clipperhouse/stringish", "github.com/clipperhouse/uax29/v2/graphemes", "github.com/cloudflare/circl/dh/x25519", "github.com/cloudflare/circl/dh/x448", "github.com/cloudflare/circl/ecc/goldilocks", "github.com/cloudflare/circl/math", "github.com/cloudflare/circl/math/fp25519", "github.com/cloudflare/circl/math/fp448", "github.com/cloudflare/circl/math/mlsbset", "github.com/cloudflare/circl/sign", "github.com/cloudflare/circl/sign/ed25519", "github.com/cloudflare/circl/sign/ed448", "github.com/containerd/errdefs", "github.com/containerd/errdefs/pkg/errhttp", "github.com/containerd/stargz-snapshotter/estargz", "github.com/containerd/stargz-snapshotter/estargz/errorutil", "github.com/coreos/go-oidc/v3/oidc", "github.com/crossplane/crossplane-runtime/v2/pkg/errors", "github.com/crossplane/crossplane-runtime/v2/pkg/fieldpath", "github.com/crossplane/crossplane-runtime/v2/pkg/logging", "github.com/crossplane/crossplane-runtime/v2/pkg/meta", "github.com/crossplane/crossplane-runtime/v2/pkg/resource", "github.com/crossplane/crossplane-runtime/v2/pkg/resource/unstructured", "github.com/crossplane/crossplane-runtime/v2/pkg/resource/unstructured/claim", "github.com/crossplane/crossplane-runtime/v2/pkg/resource/unstructured/composed", "github.com/crossplane/crossplane-runtime/v2/pkg/resource/unstructured/composite", "github.com/crossplane/crossplane-runtime/v2/pkg/resource/unstructured/reference", "github.com/crossplane/crossplane-runtime/v2/pkg/test", "github.com/crossplane/crossplane-runtime/v2/pkg/version", "github.com/crossplane/crossplane-runtime/v2/pkg/xcrd", "github.com/crossplane/crossplane-runtime/v2/pkg/xpkg", "github.com/crossplane/crossplane-runtime/v2/pkg/xpkg/parser", "github.com/crossplane/crossplane-runtime/v2/pkg/xpkg/parser/examples", "github.com/crossplane/crossplane-runtime/v2/pkg/xpkg/parser/yaml", "github.com/crossplane/crossplane-runtime/v2/pkg/xpkg/signature", "github.com/crossplane/crossplane/apis/v2/apiextensions/v1", "github.com/crossplane/crossplane/apis/v2/apiextensions/v1alpha1", "github.com/crossplane/crossplane/apis/v2/apiextensions/v1beta1", "github.com/crossplane/crossplane/apis/v2/apiextensions/v2", "github.com/crossplane/crossplane/apis/v2/core/v2", "github.com/crossplane/crossplane/apis/v2/ops/v1alpha1", "github.com/crossplane/crossplane/apis/v2/pkg", "github.com/crossplane/crossplane/apis/v2/pkg/meta/v1", "github.com/crossplane/crossplane/apis/v2/pkg/meta/v1alpha1", "github.com/crossplane/crossplane/apis/v2/pkg/meta/v1beta1", "github.com/crossplane/crossplane/apis/v2/pkg/v1", "github.com/crossplane/crossplane/apis/v2/pkg/v1beta1", "github.com/crossplane/function-sdk-go/errors", "github.com/crossplane/function-sdk-go/proto/v1", "github.com/crossplane/function-sdk-go/resource", "github.com/crossplane/function-sdk-go/resource/composed", "github.com/crossplane/function-sdk-go/resource/composite", "github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer", "github.com/cyphar/filepath-securejoin", "github.com/davecgh/go-spew/spew", "github.com/digitorus/pkcs7", "github.com/digitorus/timestamp", "github.com/dimchansky/utfbom", "github.com/distribution/reference", "github.com/dlclark/regexp2", "github.com/dlclark/regexp2/syntax", "github.com/docker/cli/cli/config", "github.com/docker/cli/cli/config/configfile", "github.com/docker/cli/cli/config/credentials", "github.com/docker/cli/cli/config/memorystore", "github.com/docker/cli/cli/config/types", "github.com/docker/distribution/registry/client/auth/challenge", "github.com/docker/docker-credential-helpers/client", "github.com/docker/docker-credential-helpers/credentials", "github.com/docker/docker/api", "github.com/docker/docker/api/types", "github.com/docker/docker/api/types/blkiodev", "github.com/docker/docker/api/types/build", "github.com/docker/docker/api/types/checkpoint", "github.com/docker/docker/api/types/common", "github.com/docker/docker/api/types/container", "github.com/docker/docker/api/types/events", "github.com/docker/docker/api/types/filters", "github.com/docker/docker/api/types/image", "github.com/docker/docker/api/types/mount", "github.com/docker/docker/api/types/network", "github.com/docker/docker/api/types/registry", "github.com/docker/docker/api/types/storage", "github.com/docker/docker/api/types/strslice", "github.com/docker/docker/api/types/swarm", "github.com/docker/docker/api/types/swarm/runtime", "github.com/docker/docker/api/types/system", "github.com/docker/docker/api/types/time", "github.com/docker/docker/api/types/versions", "github.com/docker/docker/api/types/volume", "github.com/docker/docker/client", "github.com/docker/docker/pkg/stdcopy", "github.com/docker/go-connections/nat", "github.com/docker/go-connections/sockets", "github.com/docker/go-connections/tlsconfig", "github.com/docker/go-units", "github.com/dustin/go-humanize", "github.com/emicklei/dot", "github.com/emicklei/go-restful/v3", "github.com/emicklei/go-restful/v3/log", "github.com/emirpasic/gods/containers", "github.com/emirpasic/gods/lists", "github.com/emirpasic/gods/lists/arraylist", "github.com/emirpasic/gods/trees", "github.com/emirpasic/gods/trees/binaryheap", "github.com/emirpasic/gods/utils", "github.com/evanphx/json-patch/v5", "github.com/felixge/httpsnoop", "github.com/fsnotify/fsnotify", "github.com/fxamacker/cbor/v2", "github.com/go-chi/chi/v5", "github.com/go-chi/chi/v5/middleware", "github.com/go-git/gcfg", "github.com/go-git/gcfg/scanner", "github.com/go-git/gcfg/token", "github.com/go-git/gcfg/types", "github.com/go-git/go-billy/v5", "github.com/go-git/go-billy/v5/helper/chroot", "github.com/go-git/go-billy/v5/helper/polyfill", "github.com/go-git/go-billy/v5/osfs", "github.com/go-git/go-billy/v5/util", "github.com/go-git/go-git/v5", "github.com/go-git/go-git/v5/config", "github.com/go-git/go-git/v5/plumbing", "github.com/go-git/go-git/v5/plumbing/cache", "github.com/go-git/go-git/v5/plumbing/color", "github.com/go-git/go-git/v5/plumbing/filemode", "github.com/go-git/go-git/v5/plumbing/format/config", "github.com/go-git/go-git/v5/plumbing/format/diff", "github.com/go-git/go-git/v5/plumbing/format/gitignore", "github.com/go-git/go-git/v5/plumbing/format/idxfile", "github.com/go-git/go-git/v5/plumbing/format/index", "github.com/go-git/go-git/v5/plumbing/format/objfile", "github.com/go-git/go-git/v5/plumbing/format/packfile", "github.com/go-git/go-git/v5/plumbing/format/pktline", "github.com/go-git/go-git/v5/plumbing/hash", "github.com/go-git/go-git/v5/plumbing/object", "github.com/go-git/go-git/v5/plumbing/protocol/packp", "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability", "github.com/go-git/go-git/v5/plumbing/protocol/packp/sideband", "github.com/go-git/go-git/v5/plumbing/revlist", "github.com/go-git/go-git/v5/plumbing/storer", "github.com/go-git/go-git/v5/plumbing/transport", "github.com/go-git/go-git/v5/plumbing/transport/client", "github.com/go-git/go-git/v5/plumbing/transport/file", "github.com/go-git/go-git/v5/plumbing/transport/git", "github.com/go-git/go-git/v5/plumbing/transport/http", "github.com/go-git/go-git/v5/plumbing/transport/server", "github.com/go-git/go-git/v5/plumbing/transport/ssh", "github.com/go-git/go-git/v5/storage", "github.com/go-git/go-git/v5/storage/filesystem", "github.com/go-git/go-git/v5/storage/filesystem/dotgit", "github.com/go-git/go-git/v5/storage/memory", "github.com/go-git/go-git/v5/utils/binary", "github.com/go-git/go-git/v5/utils/diff", "github.com/go-git/go-git/v5/utils/ioutil", "github.com/go-git/go-git/v5/utils/merkletrie", "github.com/go-git/go-git/v5/utils/merkletrie/filesystem", "github.com/go-git/go-git/v5/utils/merkletrie/index", "github.com/go-git/go-git/v5/utils/merkletrie/noder", "github.com/go-git/go-git/v5/utils/sync", "github.com/go-git/go-git/v5/utils/trace", "github.com/go-jose/go-jose/v4", "github.com/go-jose/go-jose/v4/cipher", "github.com/go-jose/go-jose/v4/json", "github.com/go-json-experiment/json", "github.com/go-json-experiment/json/jsontext", "github.com/go-logr/logr", "github.com/go-logr/logr/funcr", "github.com/go-logr/logr/slogr", "github.com/go-logr/stdr", "github.com/go-logr/zapr", "github.com/go-openapi/analysis", "github.com/go-openapi/errors", "github.com/go-openapi/jsonpointer", "github.com/go-openapi/jsonreference", "github.com/go-openapi/loads", "github.com/go-openapi/runtime", "github.com/go-openapi/runtime/client", "github.com/go-openapi/runtime/logger", "github.com/go-openapi/runtime/middleware", "github.com/go-openapi/runtime/middleware/denco", "github.com/go-openapi/runtime/middleware/header", "github.com/go-openapi/runtime/middleware/untyped", "github.com/go-openapi/runtime/security", "github.com/go-openapi/runtime/yamlpc", "github.com/go-openapi/spec", "github.com/go-openapi/strfmt", "github.com/go-openapi/swag", "github.com/go-openapi/swag/cmdutils", "github.com/go-openapi/swag/conv", "github.com/go-openapi/swag/fileutils", "github.com/go-openapi/swag/jsonname", "github.com/go-openapi/swag/jsonutils", "github.com/go-openapi/swag/jsonutils/adapters", "github.com/go-openapi/swag/jsonutils/adapters/ifaces", "github.com/go-openapi/swag/jsonutils/adapters/stdlib/json", "github.com/go-openapi/swag/loading", "github.com/go-openapi/swag/mangling", "github.com/go-openapi/swag/netutils", "github.com/go-openapi/swag/stringutils", "github.com/go-openapi/swag/typeutils", "github.com/go-openapi/swag/yamlutils", "github.com/go-openapi/validate", "github.com/go-viper/mapstructure/v2", "github.com/golang-jwt/jwt/v4", "github.com/golang/groupcache/lru", "github.com/golang/snappy", "github.com/google/btree", "github.com/google/cel-go/cel", "github.com/google/cel-go/checker", "github.com/google/cel-go/checker/decls", "github.com/google/cel-go/common", "github.com/google/cel-go/common/ast", "github.com/google/cel-go/common/containers", "github.com/google/cel-go/common/debug", "github.com/google/cel-go/common/decls", "github.com/google/cel-go/common/env", "github.com/google/cel-go/common/functions", "github.com/google/cel-go/common/operators", "github.com/google/cel-go/common/overloads", "github.com/google/cel-go/common/runes", "github.com/google/cel-go/common/stdlib", "github.com/google/cel-go/common/types", "github.com/google/cel-go/common/types/pb", "github.com/google/cel-go/common/types/ref", "github.com/google/cel-go/common/types/traits", "github.com/google/cel-go/ext", "github.com/google/cel-go/interpreter", "github.com/google/cel-go/interpreter/functions", "github.com/google/cel-go/parser", "github.com/google/cel-go/parser/gen", "github.com/google/certificate-transparency-go", "github.com/google/certificate-transparency-go/asn1", "github.com/google/certificate-transparency-go/client", "github.com/google/certificate-transparency-go/client/configpb", "github.com/google/certificate-transparency-go/ctutil", "github.com/google/certificate-transparency-go/gossip/minimal/x509ext", "github.com/google/certificate-transparency-go/jsonclient", "github.com/google/certificate-transparency-go/loglist3", "github.com/google/certificate-transparency-go/tls", "github.com/google/certificate-transparency-go/x509", "github.com/google/certificate-transparency-go/x509/pkix", "github.com/google/certificate-transparency-go/x509util", "github.com/google/gnostic-models/compiler", "github.com/google/gnostic-models/extensions", "github.com/google/gnostic-models/jsonschema", "github.com/google/gnostic-models/openapiv2", "github.com/google/gnostic-models/openapiv3", "github.com/google/go-cmp/cmp", "github.com/google/go-cmp/cmp/cmpopts", "github.com/google/go-containerregistry/pkg/authn", "github.com/google/go-containerregistry/pkg/authn/k8schain", "github.com/google/go-containerregistry/pkg/authn/kubernetes", "github.com/google/go-containerregistry/pkg/compression", "github.com/google/go-containerregistry/pkg/crane", "github.com/google/go-containerregistry/pkg/legacy", "github.com/google/go-containerregistry/pkg/legacy/tarball", "github.com/google/go-containerregistry/pkg/logs", "github.com/google/go-containerregistry/pkg/name", "github.com/google/go-containerregistry/pkg/v1", "github.com/google/go-containerregistry/pkg/v1/daemon", "github.com/google/go-containerregistry/pkg/v1/empty", "github.com/google/go-containerregistry/pkg/v1/google", "github.com/google/go-containerregistry/pkg/v1/layout", "github.com/google/go-containerregistry/pkg/v1/match", "github.com/google/go-containerregistry/pkg/v1/mutate", "github.com/google/go-containerregistry/pkg/v1/partial", "github.com/google/go-containerregistry/pkg/v1/random", "github.com/google/go-containerregistry/pkg/v1/remote", "github.com/google/go-containerregistry/pkg/v1/remote/transport", "github.com/google/go-containerregistry/pkg/v1/static", "github.com/google/go-containerregistry/pkg/v1/stream", "github.com/google/go-containerregistry/pkg/v1/tarball", "github.com/google/go-containerregistry/pkg/v1/types", "github.com/google/uuid", "github.com/gorilla/css/scanner", "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options", "github.com/grpc-ecosystem/grpc-gateway/v2/runtime", "github.com/grpc-ecosystem/grpc-gateway/v2/utilities", "github.com/hashicorp/errwrap", "github.com/hashicorp/go-cleanhttp", "github.com/hashicorp/go-multierror", "github.com/hashicorp/go-retryablehttp", "github.com/in-toto/attestation/go/v1", "github.com/in-toto/in-toto-golang/in_toto", "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common", "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.1", "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2", "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1", "github.com/jbenet/go-context/io", "github.com/jedisct1/go-minisign", "github.com/json-iterator/go", "github.com/kevinburke/ssh_config", "github.com/klauspost/compress", "github.com/klauspost/compress/fse", "github.com/klauspost/compress/huff0", "github.com/klauspost/compress/zstd", "github.com/letsencrypt/boulder/core", "github.com/letsencrypt/boulder/core/proto", "github.com/letsencrypt/boulder/goodkey", "github.com/letsencrypt/boulder/identifier", "github.com/letsencrypt/boulder/probs", "github.com/letsencrypt/boulder/revocation", "github.com/liggitt/tabwriter", "github.com/lucasb-eyer/go-colorful", "github.com/mattn/go-isatty", "github.com/mattn/go-runewidth", "github.com/microcosm-cc/bluemonday", "github.com/microcosm-cc/bluemonday/css", "github.com/mitchellh/go-homedir", "github.com/moby/docker-image-spec/specs-go/v1", "github.com/moby/term", "github.com/modern-go/concurrent", "github.com/modern-go/reflect2", "github.com/muesli/ansi", "github.com/muesli/ansi/compressor", "github.com/muesli/cancelreader", "github.com/muesli/reflow/ansi", "github.com/muesli/reflow/indent", "github.com/muesli/reflow/padding", "github.com/muesli/reflow/wordwrap", "github.com/muesli/termenv", "github.com/munnerz/goautoneg", "github.com/nozzle/throttler", "github.com/oklog/ulid/v2", "github.com/opencontainers/go-digest", "github.com/opencontainers/image-spec/specs-go", "github.com/opencontainers/image-spec/specs-go/v1", "github.com/pjbgf/sha1cd", "github.com/pjbgf/sha1cd/ubc", "github.com/pkg/browser", "github.com/pkg/errors", "github.com/pmezard/go-difflib/difflib", "github.com/posener/complete", "github.com/posener/complete/cmd", "github.com/posener/complete/cmd/install", "github.com/prometheus/client_golang/prometheus", "github.com/prometheus/client_golang/prometheus/collectors", "github.com/prometheus/client_golang/prometheus/promhttp", "github.com/prometheus/client_model/go", "github.com/prometheus/common/expfmt", "github.com/prometheus/common/model", "github.com/prometheus/procfs", "github.com/rivo/uniseg", "github.com/riywo/loginshell", "github.com/sassoftware/relic/lib/pkcs7", "github.com/sassoftware/relic/lib/x509tools", "github.com/secure-systems-lab/go-securesystemslib/cjson", "github.com/secure-systems-lab/go-securesystemslib/dsse", "github.com/secure-systems-lab/go-securesystemslib/encrypted", "github.com/secure-systems-lab/go-securesystemslib/signerverifier", "github.com/sergi/go-diff/diffmatchpatch", "github.com/shibumi/go-pathspec", "github.com/sigstore/cosign/v3/pkg/blob", "github.com/sigstore/cosign/v3/pkg/cosign", "github.com/sigstore/cosign/v3/pkg/cosign/attestation", "github.com/sigstore/cosign/v3/pkg/cosign/bundle", "github.com/sigstore/cosign/v3/pkg/cosign/env", "github.com/sigstore/cosign/v3/pkg/cosign/fulcioverifier/ctutil", "github.com/sigstore/cosign/v3/pkg/oci", "github.com/sigstore/cosign/v3/pkg/oci/empty", "github.com/sigstore/cosign/v3/pkg/oci/layout", "github.com/sigstore/cosign/v3/pkg/oci/remote", "github.com/sigstore/cosign/v3/pkg/oci/signed", "github.com/sigstore/cosign/v3/pkg/oci/static", "github.com/sigstore/cosign/v3/pkg/types", "github.com/sigstore/protobuf-specs/gen/pb-go/bundle/v1", "github.com/sigstore/protobuf-specs/gen/pb-go/common/v1", "github.com/sigstore/protobuf-specs/gen/pb-go/dsse", "github.com/sigstore/protobuf-specs/gen/pb-go/rekor/v1", "github.com/sigstore/protobuf-specs/gen/pb-go/trustroot/v1", "github.com/sigstore/rekor-tiles/v2/pkg/client", "github.com/sigstore/rekor-tiles/v2/pkg/client/write", "github.com/sigstore/rekor-tiles/v2/pkg/generated/protobuf", "github.com/sigstore/rekor-tiles/v2/pkg/note", "github.com/sigstore/rekor-tiles/v2/pkg/types/verifier", "github.com/sigstore/rekor-tiles/v2/pkg/verify", "github.com/sigstore/rekor/pkg/client", "github.com/sigstore/rekor/pkg/generated/client", "github.com/sigstore/rekor/pkg/generated/client/entries", "github.com/sigstore/rekor/pkg/generated/client/index", "github.com/sigstore/rekor/pkg/generated/client/pubkey", "github.com/sigstore/rekor/pkg/generated/client/tlog", "github.com/sigstore/rekor/pkg/generated/models", "github.com/sigstore/rekor/pkg/log", "github.com/sigstore/rekor/pkg/pki", "github.com/sigstore/rekor/pkg/pki/identity", "github.com/sigstore/rekor/pkg/pki/minisign", "github.com/sigstore/rekor/pkg/pki/pgp", "github.com/sigstore/rekor/pkg/pki/pkcs7", "github.com/sigstore/rekor/pkg/pki/pkitypes", "github.com/sigstore/rekor/pkg/pki/ssh", "github.com/sigstore/rekor/pkg/pki/tuf", "github.com/sigstore/rekor/pkg/pki/x509", "github.com/sigstore/rekor/pkg/tle", "github.com/sigstore/rekor/pkg/types", "github.com/sigstore/rekor/pkg/types/dsse", "github.com/sigstore/rekor/pkg/types/dsse/v0.0.1", "github.com/sigstore/rekor/pkg/types/hashedrekord", "github.com/sigstore/rekor/pkg/types/hashedrekord/v0.0.1", "github.com/sigstore/rekor/pkg/types/intoto", "github.com/sigstore/rekor/pkg/types/intoto/v0.0.1", "github.com/sigstore/rekor/pkg/types/intoto/v0.0.2", "github.com/sigstore/rekor/pkg/types/rekord", "github.com/sigstore/rekor/pkg/types/rekord/v0.0.1", "github.com/sigstore/rekor/pkg/util", "github.com/sigstore/rekor/pkg/verify", "github.com/sigstore/sigstore-go/pkg/bundle", "github.com/sigstore/sigstore-go/pkg/fulcio/certificate", "github.com/sigstore/sigstore-go/pkg/root", "github.com/sigstore/sigstore-go/pkg/sign", "github.com/sigstore/sigstore-go/pkg/tlog", "github.com/sigstore/sigstore-go/pkg/tuf", "github.com/sigstore/sigstore-go/pkg/util", "github.com/sigstore/sigstore-go/pkg/verify", "github.com/sigstore/sigstore/pkg/cryptoutils", "github.com/sigstore/sigstore/pkg/cryptoutils/goodkey", "github.com/sigstore/sigstore/pkg/fulcioroots", "github.com/sigstore/sigstore/pkg/oauth", "github.com/sigstore/sigstore/pkg/oauthflow", "github.com/sigstore/sigstore/pkg/signature", "github.com/sigstore/sigstore/pkg/signature/dsse", "github.com/sigstore/sigstore/pkg/signature/options", "github.com/sigstore/sigstore/pkg/signature/payload", "github.com/sigstore/sigstore/pkg/tuf", "github.com/sigstore/timestamp-authority/v2/pkg/verification", "github.com/sirupsen/logrus", "github.com/skeema/knownhosts", "github.com/spf13/afero", "github.com/spf13/afero/mem", "github.com/spf13/cobra", "github.com/spf13/pflag", "github.com/syndtr/goleveldb/leveldb", "github.com/syndtr/goleveldb/leveldb/cache", "github.com/syndtr/goleveldb/leveldb/comparer", "github.com/syndtr/goleveldb/leveldb/errors", "github.com/syndtr/goleveldb/leveldb/filter", "github.com/syndtr/goleveldb/leveldb/iterator", "github.com/syndtr/goleveldb/leveldb/journal", "github.com/syndtr/goleveldb/leveldb/memdb", "github.com/syndtr/goleveldb/leveldb/opt", "github.com/syndtr/goleveldb/leveldb/storage", "github.com/syndtr/goleveldb/leveldb/table", "github.com/syndtr/goleveldb/leveldb/util", "github.com/theupdateframework/go-tuf", "github.com/theupdateframework/go-tuf/client", "github.com/theupdateframework/go-tuf/client/leveldbstore", "github.com/theupdateframework/go-tuf/data", "github.com/theupdateframework/go-tuf/pkg/keys", "github.com/theupdateframework/go-tuf/pkg/targets", "github.com/theupdateframework/go-tuf/sign", "github.com/theupdateframework/go-tuf/util", "github.com/theupdateframework/go-tuf/v2/metadata", "github.com/theupdateframework/go-tuf/v2/metadata/config", "github.com/theupdateframework/go-tuf/v2/metadata/fetcher", "github.com/theupdateframework/go-tuf/v2/metadata/trustedmetadata", "github.com/theupdateframework/go-tuf/v2/metadata/updater", "github.com/theupdateframework/go-tuf/verify", "github.com/titanous/rocacheck", "github.com/transparency-dev/formats/log", "github.com/transparency-dev/merkle", "github.com/transparency-dev/merkle/compact", "github.com/transparency-dev/merkle/proof", "github.com/transparency-dev/merkle/rfc6962", "github.com/vbatts/tar-split/archive/tar", "github.com/willabides/kongplete", "github.com/x448/float16", "github.com/xanzy/ssh-agent", "github.com/xo/terminfo", "github.com/yuin/goldmark", "github.com/yuin/goldmark-emoji", "github.com/yuin/goldmark-emoji/ast", "github.com/yuin/goldmark-emoji/definition", "github.com/yuin/goldmark/ast", "github.com/yuin/goldmark/extension", "github.com/yuin/goldmark/extension/ast", "github.com/yuin/goldmark/parser", "github.com/yuin/goldmark/renderer", "github.com/yuin/goldmark/renderer/html", "github.com/yuin/goldmark/text", "github.com/yuin/goldmark/util", "go.opentelemetry.io/auto/sdk", "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp", "go.opentelemetry.io/otel", "go.opentelemetry.io/otel/attribute", "go.opentelemetry.io/otel/baggage", "go.opentelemetry.io/otel/codes", "go.opentelemetry.io/otel/metric", "go.opentelemetry.io/otel/metric/embedded", "go.opentelemetry.io/otel/metric/noop", "go.opentelemetry.io/otel/propagation", "go.opentelemetry.io/otel/semconv/v1.37.0", "go.opentelemetry.io/otel/semconv/v1.40.0", "go.opentelemetry.io/otel/semconv/v1.40.0/httpconv", "go.opentelemetry.io/otel/trace", "go.opentelemetry.io/otel/trace/embedded", "go.opentelemetry.io/otel/trace/noop", "go.uber.org/multierr", "go.uber.org/zap", "go.uber.org/zap/buffer", "go.uber.org/zap/zapcore", "go.yaml.in/yaml/v2", "go.yaml.in/yaml/v3", "golang.org/x/crypto/argon2", "golang.org/x/crypto/blake2b", "golang.org/x/crypto/blowfish", "golang.org/x/crypto/cast5", "golang.org/x/crypto/chacha20", "golang.org/x/crypto/cryptobyte", "golang.org/x/crypto/cryptobyte/asn1", "golang.org/x/crypto/curve25519", "golang.org/x/crypto/ed25519", "golang.org/x/crypto/hkdf", "golang.org/x/crypto/nacl/secretbox", "golang.org/x/crypto/ocsp", "golang.org/x/crypto/openpgp", "golang.org/x/crypto/openpgp/armor", "golang.org/x/crypto/openpgp/elgamal", "golang.org/x/crypto/openpgp/errors", "golang.org/x/crypto/openpgp/packet", "golang.org/x/crypto/openpgp/s2k", "golang.org/x/crypto/pbkdf2", "golang.org/x/crypto/pkcs12", "golang.org/x/crypto/salsa20/salsa", "golang.org/x/crypto/scrypt", "golang.org/x/crypto/sha3", "golang.org/x/crypto/ssh", "golang.org/x/crypto/ssh/agent", "golang.org/x/crypto/ssh/knownhosts", "golang.org/x/crypto/ssh/terminal", "golang.org/x/exp/slices", "golang.org/x/mod/semver", "golang.org/x/mod/sumdb/note", "golang.org/x/net/context", "golang.org/x/net/html", "golang.org/x/net/html/atom", "golang.org/x/net/http/httpguts", "golang.org/x/net/http2", "golang.org/x/net/http2/hpack", "golang.org/x/net/idna", "golang.org/x/net/proxy", "golang.org/x/net/trace", "golang.org/x/oauth2", "golang.org/x/oauth2/authhandler", "golang.org/x/oauth2/google", "golang.org/x/oauth2/google/externalaccount", "golang.org/x/oauth2/jws", "golang.org/x/oauth2/jwt", "golang.org/x/sync/errgroup", "golang.org/x/sync/singleflight", "golang.org/x/sys/cpu", "golang.org/x/sys/execabs", "golang.org/x/sys/unix", "golang.org/x/term", "golang.org/x/text/cases", "golang.org/x/text/feature/plural", "golang.org/x/text/language", "golang.org/x/text/message", "golang.org/x/text/message/catalog", "golang.org/x/text/runes", "golang.org/x/text/secure/bidirule", "golang.org/x/text/transform", "golang.org/x/text/unicode/bidi", "golang.org/x/text/unicode/norm", "golang.org/x/time/rate", "gomodules.xyz/jsonpatch/v2", "google.golang.org/genproto/googleapis/api", "google.golang.org/genproto/googleapis/api/annotations", "google.golang.org/genproto/googleapis/api/expr/v1alpha1", "google.golang.org/genproto/googleapis/api/httpbody", "google.golang.org/genproto/googleapis/rpc/status", "google.golang.org/grpc", "google.golang.org/grpc/attributes", "google.golang.org/grpc/backoff", "google.golang.org/grpc/balancer", "google.golang.org/grpc/balancer/base", "google.golang.org/grpc/balancer/endpointsharding", "google.golang.org/grpc/balancer/grpclb/state", "google.golang.org/grpc/balancer/pickfirst", "google.golang.org/grpc/balancer/roundrobin", "google.golang.org/grpc/binarylog/grpc_binarylog_v1", "google.golang.org/grpc/channelz", "google.golang.org/grpc/codes", "google.golang.org/grpc/connectivity", "google.golang.org/grpc/credentials", "google.golang.org/grpc/credentials/insecure", "google.golang.org/grpc/encoding", "google.golang.org/grpc/encoding/proto", "google.golang.org/grpc/experimental/stats", "google.golang.org/grpc/grpclog", "google.golang.org/grpc/health/grpc_health_v1", "google.golang.org/grpc/keepalive", "google.golang.org/grpc/mem", "google.golang.org/grpc/metadata", "google.golang.org/grpc/peer", "google.golang.org/grpc/resolver", "google.golang.org/grpc/resolver/dns", "google.golang.org/grpc/serviceconfig", "google.golang.org/grpc/stats", "google.golang.org/grpc/status", "google.golang.org/grpc/tap", "google.golang.org/protobuf/encoding/protodelim", "google.golang.org/protobuf/encoding/protojson", "google.golang.org/protobuf/encoding/prototext", "google.golang.org/protobuf/encoding/protowire", "google.golang.org/protobuf/proto", "google.golang.org/protobuf/protoadapt", "google.golang.org/protobuf/reflect/protodesc", "google.golang.org/protobuf/reflect/protoreflect", "google.golang.org/protobuf/reflect/protoregistry", "google.golang.org/protobuf/runtime/protoiface", "google.golang.org/protobuf/runtime/protoimpl", "google.golang.org/protobuf/testing/protocmp", "google.golang.org/protobuf/types/descriptorpb", "google.golang.org/protobuf/types/dynamicpb", "google.golang.org/protobuf/types/gofeaturespb", "google.golang.org/protobuf/types/known/anypb", "google.golang.org/protobuf/types/known/durationpb", "google.golang.org/protobuf/types/known/emptypb", "google.golang.org/protobuf/types/known/fieldmaskpb", "google.golang.org/protobuf/types/known/structpb", "google.golang.org/protobuf/types/known/timestamppb", "google.golang.org/protobuf/types/known/wrapperspb", "gopkg.in/evanphx/json-patch.v4", "gopkg.in/inf.v0", "gopkg.in/warnings.v0", "gopkg.in/yaml.v3", "k8s.io/api/admission/v1", "k8s.io/api/admission/v1beta1", "k8s.io/api/admissionregistration/v1", "k8s.io/api/admissionregistration/v1alpha1", "k8s.io/api/admissionregistration/v1beta1", "k8s.io/api/apidiscovery/v2", "k8s.io/api/apidiscovery/v2beta1", "k8s.io/api/apiserverinternal/v1alpha1", "k8s.io/api/apps/v1", "k8s.io/api/apps/v1beta1", "k8s.io/api/apps/v1beta2", "k8s.io/api/authentication/v1", "k8s.io/api/authentication/v1alpha1", "k8s.io/api/authentication/v1beta1", "k8s.io/api/authorization/v1", "k8s.io/api/authorization/v1beta1", "k8s.io/api/autoscaling/v1", "k8s.io/api/autoscaling/v2", "k8s.io/api/autoscaling/v2beta1", "k8s.io/api/autoscaling/v2beta2", "k8s.io/api/batch/v1", "k8s.io/api/batch/v1beta1", "k8s.io/api/certificates/v1", "k8s.io/api/certificates/v1alpha1", "k8s.io/api/certificates/v1beta1", "k8s.io/api/coordination/v1", "k8s.io/api/coordination/v1alpha2", "k8s.io/api/coordination/v1beta1", "k8s.io/api/core/v1", "k8s.io/api/discovery/v1", "k8s.io/api/discovery/v1beta1", "k8s.io/api/events/v1", "k8s.io/api/events/v1beta1", "k8s.io/api/extensions/v1beta1", "k8s.io/api/flowcontrol/v1", "k8s.io/api/flowcontrol/v1beta1", "k8s.io/api/flowcontrol/v1beta2", "k8s.io/api/flowcontrol/v1beta3", "k8s.io/api/networking/v1", "k8s.io/api/networking/v1beta1", "k8s.io/api/node/v1", "k8s.io/api/node/v1alpha1", "k8s.io/api/node/v1beta1", "k8s.io/api/policy/v1", "k8s.io/api/policy/v1beta1", "k8s.io/api/rbac/v1", "k8s.io/api/rbac/v1alpha1", "k8s.io/api/rbac/v1beta1", "k8s.io/api/resource/v1", "k8s.io/api/resource/v1alpha3", "k8s.io/api/resource/v1beta1", "k8s.io/api/resource/v1beta2", "k8s.io/api/scheduling/v1", "k8s.io/api/scheduling/v1alpha1", "k8s.io/api/scheduling/v1beta1", "k8s.io/api/storage/v1", "k8s.io/api/storage/v1alpha1", "k8s.io/api/storage/v1beta1", "k8s.io/api/storagemigration/v1beta1", "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions", "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1", "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1", "k8s.io/apiextensions-apiserver/pkg/apiserver/schema", "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel", "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model", "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/defaulting", "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/objectmeta", "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/pruning", "k8s.io/apiextensions-apiserver/pkg/apiserver/validation", "k8s.io/apiextensions-apiserver/pkg/features", "k8s.io/apimachinery/pkg/api/equality", "k8s.io/apimachinery/pkg/api/errors", "k8s.io/apimachinery/pkg/api/meta", "k8s.io/apimachinery/pkg/api/meta/testrestmapper", "k8s.io/apimachinery/pkg/api/operation", "k8s.io/apimachinery/pkg/api/resource", "k8s.io/apimachinery/pkg/api/safe", "k8s.io/apimachinery/pkg/api/validate", "k8s.io/apimachinery/pkg/api/validate/constraints", "k8s.io/apimachinery/pkg/api/validate/content", "k8s.io/apimachinery/pkg/api/validation", "k8s.io/apimachinery/pkg/api/validation/path", "k8s.io/apimachinery/pkg/apis/meta/v1", "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured", "k8s.io/apimachinery/pkg/apis/meta/v1/validation", "k8s.io/apimachinery/pkg/apis/meta/v1beta1", "k8s.io/apimachinery/pkg/conversion", "k8s.io/apimachinery/pkg/conversion/queryparams", "k8s.io/apimachinery/pkg/fields", "k8s.io/apimachinery/pkg/labels", "k8s.io/apimachinery/pkg/runtime", "k8s.io/apimachinery/pkg/runtime/schema", "k8s.io/apimachinery/pkg/runtime/serializer", "k8s.io/apimachinery/pkg/runtime/serializer/cbor", "k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct", "k8s.io/apimachinery/pkg/runtime/serializer/json", "k8s.io/apimachinery/pkg/runtime/serializer/protobuf", "k8s.io/apimachinery/pkg/runtime/serializer/recognizer", "k8s.io/apimachinery/pkg/runtime/serializer/streaming", "k8s.io/apimachinery/pkg/runtime/serializer/versioning", "k8s.io/apimachinery/pkg/selection", "k8s.io/apimachinery/pkg/types", "k8s.io/apimachinery/pkg/util/cache", "k8s.io/apimachinery/pkg/util/diff", "k8s.io/apimachinery/pkg/util/dump", "k8s.io/apimachinery/pkg/util/duration", "k8s.io/apimachinery/pkg/util/errors", "k8s.io/apimachinery/pkg/util/framer", "k8s.io/apimachinery/pkg/util/intstr", "k8s.io/apimachinery/pkg/util/json", "k8s.io/apimachinery/pkg/util/managedfields", "k8s.io/apimachinery/pkg/util/mergepatch", "k8s.io/apimachinery/pkg/util/naming", "k8s.io/apimachinery/pkg/util/net", "k8s.io/apimachinery/pkg/util/rand", "k8s.io/apimachinery/pkg/util/runtime", "k8s.io/apimachinery/pkg/util/sets", "k8s.io/apimachinery/pkg/util/strategicpatch", "k8s.io/apimachinery/pkg/util/uuid", "k8s.io/apimachinery/pkg/util/validation", "k8s.io/apimachinery/pkg/util/validation/field", "k8s.io/apimachinery/pkg/util/version", "k8s.io/apimachinery/pkg/util/wait", "k8s.io/apimachinery/pkg/util/yaml", "k8s.io/apimachinery/pkg/version", "k8s.io/apimachinery/pkg/watch", "k8s.io/apimachinery/third_party/forked/golang/json", "k8s.io/apimachinery/third_party/forked/golang/reflect", "k8s.io/apiserver/pkg/apis/cel", "k8s.io/apiserver/pkg/authentication/serviceaccount", "k8s.io/apiserver/pkg/authentication/user", "k8s.io/apiserver/pkg/authorization/authorizer", "k8s.io/apiserver/pkg/cel", "k8s.io/apiserver/pkg/cel/common", "k8s.io/apiserver/pkg/cel/environment", "k8s.io/apiserver/pkg/cel/library", "k8s.io/apiserver/pkg/cel/metrics", "k8s.io/apiserver/pkg/cel/openapi", "k8s.io/apiserver/pkg/features", "k8s.io/apiserver/pkg/util/compatibility", "k8s.io/apiserver/pkg/util/feature", "k8s.io/apiserver/pkg/warning", "k8s.io/cli-runtime/pkg/printers", "k8s.io/client-go/applyconfigurations/admissionregistration/v1", "k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1", "k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1", "k8s.io/client-go/applyconfigurations/apiserverinternal/v1alpha1", "k8s.io/client-go/applyconfigurations/apps/v1", "k8s.io/client-go/applyconfigurations/apps/v1beta1", "k8s.io/client-go/applyconfigurations/apps/v1beta2", "k8s.io/client-go/applyconfigurations/autoscaling/v1", "k8s.io/client-go/applyconfigurations/autoscaling/v2", "k8s.io/client-go/applyconfigurations/autoscaling/v2beta1", "k8s.io/client-go/applyconfigurations/autoscaling/v2beta2", "k8s.io/client-go/applyconfigurations/batch/v1", "k8s.io/client-go/applyconfigurations/batch/v1beta1", "k8s.io/client-go/applyconfigurations/certificates/v1", "k8s.io/client-go/applyconfigurations/certificates/v1alpha1", "k8s.io/client-go/applyconfigurations/certificates/v1beta1", "k8s.io/client-go/applyconfigurations/coordination/v1", "k8s.io/client-go/applyconfigurations/coordination/v1alpha2", "k8s.io/client-go/applyconfigurations/coordination/v1beta1", "k8s.io/client-go/applyconfigurations/core/v1", "k8s.io/client-go/applyconfigurations/discovery/v1", "k8s.io/client-go/applyconfigurations/discovery/v1beta1", "k8s.io/client-go/applyconfigurations/events/v1", "k8s.io/client-go/applyconfigurations/events/v1beta1", "k8s.io/client-go/applyconfigurations/extensions/v1beta1", "k8s.io/client-go/applyconfigurations/flowcontrol/v1", "k8s.io/client-go/applyconfigurations/flowcontrol/v1beta1", "k8s.io/client-go/applyconfigurations/flowcontrol/v1beta2", "k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3", "k8s.io/client-go/applyconfigurations/meta/v1", "k8s.io/client-go/applyconfigurations/networking/v1", "k8s.io/client-go/applyconfigurations/networking/v1beta1", "k8s.io/client-go/applyconfigurations/node/v1", "k8s.io/client-go/applyconfigurations/node/v1alpha1", "k8s.io/client-go/applyconfigurations/node/v1beta1", "k8s.io/client-go/applyconfigurations/policy/v1", "k8s.io/client-go/applyconfigurations/policy/v1beta1", "k8s.io/client-go/applyconfigurations/rbac/v1", "k8s.io/client-go/applyconfigurations/rbac/v1alpha1", "k8s.io/client-go/applyconfigurations/rbac/v1beta1", "k8s.io/client-go/applyconfigurations/resource/v1", "k8s.io/client-go/applyconfigurations/resource/v1alpha3", "k8s.io/client-go/applyconfigurations/resource/v1beta1", "k8s.io/client-go/applyconfigurations/resource/v1beta2", "k8s.io/client-go/applyconfigurations/scheduling/v1", "k8s.io/client-go/applyconfigurations/scheduling/v1alpha1", "k8s.io/client-go/applyconfigurations/scheduling/v1beta1", "k8s.io/client-go/applyconfigurations/storage/v1", "k8s.io/client-go/applyconfigurations/storage/v1alpha1", "k8s.io/client-go/applyconfigurations/storage/v1beta1", "k8s.io/client-go/applyconfigurations/storagemigration/v1beta1", "k8s.io/client-go/discovery", "k8s.io/client-go/discovery/cached/memory", "k8s.io/client-go/dynamic", "k8s.io/client-go/features", "k8s.io/client-go/gentype", "k8s.io/client-go/informers", "k8s.io/client-go/informers/admissionregistration", "k8s.io/client-go/informers/admissionregistration/v1", "k8s.io/client-go/informers/admissionregistration/v1alpha1", "k8s.io/client-go/informers/admissionregistration/v1beta1", "k8s.io/client-go/informers/apiserverinternal", "k8s.io/client-go/informers/apiserverinternal/v1alpha1", "k8s.io/client-go/informers/apps", "k8s.io/client-go/informers/apps/v1", "k8s.io/client-go/informers/apps/v1beta1", "k8s.io/client-go/informers/apps/v1beta2", "k8s.io/client-go/informers/autoscaling", "k8s.io/client-go/informers/autoscaling/v1", "k8s.io/client-go/informers/autoscaling/v2", "k8s.io/client-go/informers/autoscaling/v2beta1", "k8s.io/client-go/informers/autoscaling/v2beta2", "k8s.io/client-go/informers/batch", "k8s.io/client-go/informers/batch/v1", "k8s.io/client-go/informers/batch/v1beta1", "k8s.io/client-go/informers/certificates", "k8s.io/client-go/informers/certificates/v1", "k8s.io/client-go/informers/certificates/v1alpha1", "k8s.io/client-go/informers/certificates/v1beta1", "k8s.io/client-go/informers/coordination", "k8s.io/client-go/informers/coordination/v1", "k8s.io/client-go/informers/coordination/v1alpha2", "k8s.io/client-go/informers/coordination/v1beta1", "k8s.io/client-go/informers/core", "k8s.io/client-go/informers/core/v1", "k8s.io/client-go/informers/discovery", "k8s.io/client-go/informers/discovery/v1", "k8s.io/client-go/informers/discovery/v1beta1", "k8s.io/client-go/informers/events", "k8s.io/client-go/informers/events/v1", "k8s.io/client-go/informers/events/v1beta1", "k8s.io/client-go/informers/extensions", "k8s.io/client-go/informers/extensions/v1beta1", "k8s.io/client-go/informers/flowcontrol", "k8s.io/client-go/informers/flowcontrol/v1", "k8s.io/client-go/informers/flowcontrol/v1beta1", "k8s.io/client-go/informers/flowcontrol/v1beta2", "k8s.io/client-go/informers/flowcontrol/v1beta3", "k8s.io/client-go/informers/networking", "k8s.io/client-go/informers/networking/v1", "k8s.io/client-go/informers/networking/v1beta1", "k8s.io/client-go/informers/node", "k8s.io/client-go/informers/node/v1", "k8s.io/client-go/informers/node/v1alpha1", "k8s.io/client-go/informers/node/v1beta1", "k8s.io/client-go/informers/policy", "k8s.io/client-go/informers/policy/v1", "k8s.io/client-go/informers/policy/v1beta1", "k8s.io/client-go/informers/rbac", "k8s.io/client-go/informers/rbac/v1", "k8s.io/client-go/informers/rbac/v1alpha1", "k8s.io/client-go/informers/rbac/v1beta1", "k8s.io/client-go/informers/resource", "k8s.io/client-go/informers/resource/v1", "k8s.io/client-go/informers/resource/v1alpha3", "k8s.io/client-go/informers/resource/v1beta1", "k8s.io/client-go/informers/resource/v1beta2", "k8s.io/client-go/informers/scheduling", "k8s.io/client-go/informers/scheduling/v1", "k8s.io/client-go/informers/scheduling/v1alpha1", "k8s.io/client-go/informers/scheduling/v1beta1", "k8s.io/client-go/informers/storage", "k8s.io/client-go/informers/storage/v1", "k8s.io/client-go/informers/storage/v1alpha1", "k8s.io/client-go/informers/storage/v1beta1", "k8s.io/client-go/informers/storagemigration", "k8s.io/client-go/informers/storagemigration/v1beta1", "k8s.io/client-go/kubernetes", "k8s.io/client-go/kubernetes/scheme", "k8s.io/client-go/kubernetes/typed/admissionregistration/v1", "k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1", "k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1", "k8s.io/client-go/kubernetes/typed/apiserverinternal/v1alpha1", "k8s.io/client-go/kubernetes/typed/apps/v1", "k8s.io/client-go/kubernetes/typed/apps/v1beta1", "k8s.io/client-go/kubernetes/typed/apps/v1beta2", "k8s.io/client-go/kubernetes/typed/authentication/v1", "k8s.io/client-go/kubernetes/typed/authentication/v1alpha1", "k8s.io/client-go/kubernetes/typed/authentication/v1beta1", "k8s.io/client-go/kubernetes/typed/authorization/v1", "k8s.io/client-go/kubernetes/typed/authorization/v1beta1", "k8s.io/client-go/kubernetes/typed/autoscaling/v1", "k8s.io/client-go/kubernetes/typed/autoscaling/v2", "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1", "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta2", "k8s.io/client-go/kubernetes/typed/batch/v1", "k8s.io/client-go/kubernetes/typed/batch/v1beta1", "k8s.io/client-go/kubernetes/typed/certificates/v1", "k8s.io/client-go/kubernetes/typed/certificates/v1alpha1", "k8s.io/client-go/kubernetes/typed/certificates/v1beta1", "k8s.io/client-go/kubernetes/typed/coordination/v1", "k8s.io/client-go/kubernetes/typed/coordination/v1alpha2", "k8s.io/client-go/kubernetes/typed/coordination/v1beta1", "k8s.io/client-go/kubernetes/typed/core/v1", "k8s.io/client-go/kubernetes/typed/discovery/v1", "k8s.io/client-go/kubernetes/typed/discovery/v1beta1", "k8s.io/client-go/kubernetes/typed/events/v1", "k8s.io/client-go/kubernetes/typed/events/v1beta1", "k8s.io/client-go/kubernetes/typed/extensions/v1beta1", "k8s.io/client-go/kubernetes/typed/flowcontrol/v1", "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1", "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta2", "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3", "k8s.io/client-go/kubernetes/typed/networking/v1", "k8s.io/client-go/kubernetes/typed/networking/v1beta1", "k8s.io/client-go/kubernetes/typed/node/v1", "k8s.io/client-go/kubernetes/typed/node/v1alpha1", "k8s.io/client-go/kubernetes/typed/node/v1beta1", "k8s.io/client-go/kubernetes/typed/policy/v1", "k8s.io/client-go/kubernetes/typed/policy/v1beta1", "k8s.io/client-go/kubernetes/typed/rbac/v1", "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1", "k8s.io/client-go/kubernetes/typed/rbac/v1beta1", "k8s.io/client-go/kubernetes/typed/resource/v1", "k8s.io/client-go/kubernetes/typed/resource/v1alpha3", "k8s.io/client-go/kubernetes/typed/resource/v1beta1", "k8s.io/client-go/kubernetes/typed/resource/v1beta2", "k8s.io/client-go/kubernetes/typed/scheduling/v1", "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1", "k8s.io/client-go/kubernetes/typed/scheduling/v1beta1", "k8s.io/client-go/kubernetes/typed/storage/v1", "k8s.io/client-go/kubernetes/typed/storage/v1alpha1", "k8s.io/client-go/kubernetes/typed/storage/v1beta1", "k8s.io/client-go/kubernetes/typed/storagemigration/v1beta1", "k8s.io/client-go/listers", "k8s.io/client-go/listers/admissionregistration/v1", "k8s.io/client-go/listers/admissionregistration/v1alpha1", "k8s.io/client-go/listers/admissionregistration/v1beta1", "k8s.io/client-go/listers/apiserverinternal/v1alpha1", "k8s.io/client-go/listers/apps/v1", "k8s.io/client-go/listers/apps/v1beta1", "k8s.io/client-go/listers/apps/v1beta2", "k8s.io/client-go/listers/autoscaling/v1", "k8s.io/client-go/listers/autoscaling/v2", "k8s.io/client-go/listers/autoscaling/v2beta1", "k8s.io/client-go/listers/autoscaling/v2beta2", "k8s.io/client-go/listers/batch/v1", "k8s.io/client-go/listers/batch/v1beta1", "k8s.io/client-go/listers/certificates/v1", "k8s.io/client-go/listers/certificates/v1alpha1", "k8s.io/client-go/listers/certificates/v1beta1", "k8s.io/client-go/listers/coordination/v1", "k8s.io/client-go/listers/coordination/v1alpha2", "k8s.io/client-go/listers/coordination/v1beta1", "k8s.io/client-go/listers/core/v1", "k8s.io/client-go/listers/discovery/v1", "k8s.io/client-go/listers/discovery/v1beta1", "k8s.io/client-go/listers/events/v1", "k8s.io/client-go/listers/events/v1beta1", "k8s.io/client-go/listers/extensions/v1beta1", "k8s.io/client-go/listers/flowcontrol/v1", "k8s.io/client-go/listers/flowcontrol/v1beta1", "k8s.io/client-go/listers/flowcontrol/v1beta2", "k8s.io/client-go/listers/flowcontrol/v1beta3", "k8s.io/client-go/listers/networking/v1", "k8s.io/client-go/listers/networking/v1beta1", "k8s.io/client-go/listers/node/v1", "k8s.io/client-go/listers/node/v1alpha1", "k8s.io/client-go/listers/node/v1beta1", "k8s.io/client-go/listers/policy/v1", "k8s.io/client-go/listers/policy/v1beta1", "k8s.io/client-go/listers/rbac/v1", "k8s.io/client-go/listers/rbac/v1alpha1", "k8s.io/client-go/listers/rbac/v1beta1", "k8s.io/client-go/listers/resource/v1", "k8s.io/client-go/listers/resource/v1alpha3", "k8s.io/client-go/listers/resource/v1beta1", "k8s.io/client-go/listers/resource/v1beta2", "k8s.io/client-go/listers/scheduling/v1", "k8s.io/client-go/listers/scheduling/v1alpha1", "k8s.io/client-go/listers/scheduling/v1beta1", "k8s.io/client-go/listers/storage/v1", "k8s.io/client-go/listers/storage/v1alpha1", "k8s.io/client-go/listers/storage/v1beta1", "k8s.io/client-go/listers/storagemigration/v1beta1", "k8s.io/client-go/metadata", "k8s.io/client-go/openapi", "k8s.io/client-go/openapi/cached", "k8s.io/client-go/pkg/apis/clientauthentication", "k8s.io/client-go/pkg/apis/clientauthentication/install", "k8s.io/client-go/pkg/apis/clientauthentication/v1", "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1", "k8s.io/client-go/pkg/version", "k8s.io/client-go/plugin/pkg/client/auth", "k8s.io/client-go/plugin/pkg/client/auth/azure", "k8s.io/client-go/plugin/pkg/client/auth/exec", "k8s.io/client-go/plugin/pkg/client/auth/gcp", "k8s.io/client-go/plugin/pkg/client/auth/oidc", "k8s.io/client-go/rest", "k8s.io/client-go/rest/watch", "k8s.io/client-go/restmapper", "k8s.io/client-go/testing", "k8s.io/client-go/third_party/forked/golang/template", "k8s.io/client-go/tools/auth", "k8s.io/client-go/tools/cache", "k8s.io/client-go/tools/cache/synctrack", "k8s.io/client-go/tools/clientcmd", "k8s.io/client-go/tools/clientcmd/api", "k8s.io/client-go/tools/clientcmd/api/latest", "k8s.io/client-go/tools/clientcmd/api/v1", "k8s.io/client-go/tools/events", "k8s.io/client-go/tools/leaderelection", "k8s.io/client-go/tools/leaderelection/resourcelock", "k8s.io/client-go/tools/metrics", "k8s.io/client-go/tools/pager", "k8s.io/client-go/tools/record", "k8s.io/client-go/tools/record/util", "k8s.io/client-go/tools/reference", "k8s.io/client-go/transport", "k8s.io/client-go/util/apply", "k8s.io/client-go/util/cert", "k8s.io/client-go/util/connrotation", "k8s.io/client-go/util/consistencydetector", "k8s.io/client-go/util/flowcontrol", "k8s.io/client-go/util/homedir", "k8s.io/client-go/util/jsonpath", "k8s.io/client-go/util/keyutil", "k8s.io/client-go/util/retry", "k8s.io/client-go/util/watchlist", "k8s.io/client-go/util/workqueue", "k8s.io/component-base/cli/flag", "k8s.io/component-base/compatibility", "k8s.io/component-base/featuregate", "k8s.io/component-base/metrics", "k8s.io/component-base/metrics/legacyregistry", "k8s.io/component-base/metrics/prometheus/compatversion", "k8s.io/component-base/metrics/prometheus/feature", "k8s.io/component-base/metrics/prometheusextension", "k8s.io/component-base/version", "k8s.io/component-base/zpages/features", "k8s.io/klog/v2", "k8s.io/kube-openapi/pkg/cached", "k8s.io/kube-openapi/pkg/common", "k8s.io/kube-openapi/pkg/handler3", "k8s.io/kube-openapi/pkg/schemaconv", "k8s.io/kube-openapi/pkg/spec3", "k8s.io/kube-openapi/pkg/util", "k8s.io/kube-openapi/pkg/util/proto", "k8s.io/kube-openapi/pkg/validation/errors", "k8s.io/kube-openapi/pkg/validation/spec", "k8s.io/kube-openapi/pkg/validation/strfmt", "k8s.io/kube-openapi/pkg/validation/strfmt/bson", "k8s.io/kube-openapi/pkg/validation/validate", "k8s.io/metrics/pkg/apis/metrics", "k8s.io/metrics/pkg/apis/metrics/v1alpha1", "k8s.io/metrics/pkg/apis/metrics/v1beta1", "k8s.io/metrics/pkg/client/clientset/versioned", "k8s.io/metrics/pkg/client/clientset/versioned/scheme", "k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1alpha1", "k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1beta1", "k8s.io/utils/buffer", "k8s.io/utils/clock", "k8s.io/utils/lru", "k8s.io/utils/net", "k8s.io/utils/ptr", "k8s.io/utils/trace", "sigs.k8s.io/controller-runtime", "sigs.k8s.io/controller-runtime/pkg/builder", "sigs.k8s.io/controller-runtime/pkg/cache", "sigs.k8s.io/controller-runtime/pkg/certwatcher", "sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics", "sigs.k8s.io/controller-runtime/pkg/client", "sigs.k8s.io/controller-runtime/pkg/client/apiutil", "sigs.k8s.io/controller-runtime/pkg/client/config", "sigs.k8s.io/controller-runtime/pkg/cluster", "sigs.k8s.io/controller-runtime/pkg/config", "sigs.k8s.io/controller-runtime/pkg/controller", "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil", "sigs.k8s.io/controller-runtime/pkg/controller/priorityqueue", "sigs.k8s.io/controller-runtime/pkg/conversion", "sigs.k8s.io/controller-runtime/pkg/event", "sigs.k8s.io/controller-runtime/pkg/handler", "sigs.k8s.io/controller-runtime/pkg/healthz", "sigs.k8s.io/controller-runtime/pkg/leaderelection", "sigs.k8s.io/controller-runtime/pkg/log", "sigs.k8s.io/controller-runtime/pkg/log/zap", "sigs.k8s.io/controller-runtime/pkg/manager", "sigs.k8s.io/controller-runtime/pkg/manager/signals", "sigs.k8s.io/controller-runtime/pkg/metrics", "sigs.k8s.io/controller-runtime/pkg/metrics/server", "sigs.k8s.io/controller-runtime/pkg/predicate", "sigs.k8s.io/controller-runtime/pkg/reconcile", "sigs.k8s.io/controller-runtime/pkg/recorder", "sigs.k8s.io/controller-runtime/pkg/scheme", "sigs.k8s.io/controller-runtime/pkg/source", "sigs.k8s.io/controller-runtime/pkg/webhook", "sigs.k8s.io/controller-runtime/pkg/webhook/admission", "sigs.k8s.io/controller-runtime/pkg/webhook/admission/metrics", "sigs.k8s.io/controller-runtime/pkg/webhook/conversion", "sigs.k8s.io/controller-runtime/pkg/webhook/conversion/metrics", "sigs.k8s.io/json", "sigs.k8s.io/randfill", "sigs.k8s.io/randfill/bytesource", "sigs.k8s.io/structured-merge-diff/v6/fieldpath", "sigs.k8s.io/structured-merge-diff/v6/merge", "sigs.k8s.io/structured-merge-diff/v6/schema", "sigs.k8s.io/structured-merge-diff/v6/typed", "sigs.k8s.io/structured-merge-diff/v6/value", "sigs.k8s.io/yaml", "sigs.k8s.io/yaml/kyaml"] [mod] [mod."cel.dev/expr"] @@ -50,6 +50,9 @@ cachePackages = ["cel.dev/expr", "cloud.google.com/go/compute/metadata", "dario. [mod."github.com/ProtonMail/go-crypto"] version = "v1.1.6" hash = "sha256-XlFT3uxgpPYFTND54uO8fH33jtQqAHWa7zrv24nw/PE=" + [mod."github.com/alecthomas/chroma/v2"] + version = "v2.20.0" + hash = "sha256-rL1mJS8fCltcii9w/efyyE4iyzogyjP+N80lE3CuzVE=" [mod."github.com/alecthomas/kong"] version = "v1.14.0" hash = "sha256-F6BYciiFpdtjKosD+L+z0Sc2s903iD2ElbytjcM4mas=" @@ -113,6 +116,9 @@ cachePackages = ["cel.dev/expr", "cloud.google.com/go/compute/metadata", "dario. [mod."github.com/aymanbagabas/go-osc52/v2"] version = "v2.0.1" hash = "sha256-6Bp0jBZ6npvsYcKZGHHIUSVSTAMEyieweAX2YAKDjjg=" + [mod."github.com/aymerick/douceur"] + version = "v0.2.0" + hash = "sha256-NiBX8EfOvLXNiK3pJaZX4N73YgfzdrzRXdiBFe3X3sE=" [mod."github.com/beorn7/perks"] version = "v1.0.1" hash = "sha256-h75GUqfwJKngCJQVE5Ao5wnO3cfKD9lSIteoLp/3xJ4=" @@ -134,15 +140,21 @@ cachePackages = ["cel.dev/expr", "cloud.google.com/go/compute/metadata", "dario. [mod."github.com/charmbracelet/colorprofile"] version = "v0.4.1" hash = "sha256-d/NjM/ybG+bGRRRMMcjbPCFGFS5noZRMaL05Ix5r/II=" + [mod."github.com/charmbracelet/glamour"] + version = "v1.0.0" + hash = "sha256-1sGgVA3QXJ2P5c/DNMb7R0HFG1X5vz9nmDhLrzKdgMw=" [mod."github.com/charmbracelet/lipgloss"] - version = "v1.1.0" - hash = "sha256-RHsRT2EZ1nDOElxAK+6/DC9XAaGVjDTgPvRh3pyCfY4=" + version = "v1.1.1-0.20250404203927-76690c660834" + hash = "sha256-CwS1AyoRsPOFA4SrC0CTtwLnbg57FmmSW/mvVQUFYcc=" [mod."github.com/charmbracelet/x/ansi"] version = "v0.11.6" hash = "sha256-UToZIkqXl9MEppcRgbeBqaaMeAzRkGa0w3lVUs6sxWI=" [mod."github.com/charmbracelet/x/cellbuf"] version = "v0.0.15" hash = "sha256-0S60XaWhKZG+TB3Kqe1oMn2Okwdq53nym8XayVSHHiM=" + [mod."github.com/charmbracelet/x/exp/slice"] + version = "v0.0.0-20250327172914-2fdc97757edf" + hash = "sha256-C1tksnevc/RdytJRQg5LQ0+VVSWlTwbNGic649m6E1Q=" [mod."github.com/charmbracelet/x/term"] version = "v0.2.2" hash = "sha256-KF7IU1Luxl/sZP6XjomWB2e3lxSUS4/5AahhapGir/4=" @@ -203,6 +215,9 @@ cachePackages = ["cel.dev/expr", "cloud.google.com/go/compute/metadata", "dario. [mod."github.com/distribution/reference"] version = "v0.6.0" hash = "sha256-gr4tL+qz4jKyAtl8LINcxMSanztdt+pybj1T+2ulQv4=" + [mod."github.com/dlclark/regexp2"] + version = "v1.11.5" + hash = "sha256-jN5+2ED+YbIoPIuyJ4Ou5pqJb2w1uNKzp5yTjKY6rEQ=" [mod."github.com/docker/cli"] version = "v29.4.0+incompatible" hash = "sha256-mUN7Fu9e4ahtUJBUvCHUk+ICFq1d6vs7MoJf0/cw+mA=" @@ -383,6 +398,9 @@ cachePackages = ["cel.dev/expr", "cloud.google.com/go/compute/metadata", "dario. [mod."github.com/google/uuid"] version = "v1.6.0" hash = "sha256-VWl9sqUzdOuhW0KzQlv0gwwUQClYkmZwSydHG2sALYw=" + [mod."github.com/gorilla/css"] + version = "v1.0.1" + hash = "sha256-6JwNHqlY2NpZ0pSQTyYPSpiNqjXOdFHqrUT10sv3y8A=" [mod."github.com/grpc-ecosystem/grpc-gateway/v2"] version = "v2.28.0" hash = "sha256-QeWb6jN6noeGPCzECgpUSb9YX9LzvKGwImEuX+A03gs=" @@ -443,6 +461,9 @@ cachePackages = ["cel.dev/expr", "cloud.google.com/go/compute/metadata", "dario. [mod."github.com/mattn/go-runewidth"] version = "v0.0.19" hash = "sha256-GpnbKplhX410Q/eIdknvWbYZgdav1keN+7wNUeOSMHE=" + [mod."github.com/microcosm-cc/bluemonday"] + version = "v1.0.27" + hash = "sha256-EZSya9FLPQ83CL7N2cZy21fdS35hViTkiMK5f3op8Es=" [mod."github.com/mitchellh/go-homedir"] version = "v1.1.0" hash = "sha256-oduBKXHAQG8X6aqLEpqZHs5DOKe84u6WkBwi4W6cv3k=" @@ -467,6 +488,9 @@ cachePackages = ["cel.dev/expr", "cloud.google.com/go/compute/metadata", "dario. [mod."github.com/muesli/cancelreader"] version = "v0.2.2" hash = "sha256-uEPpzwRJBJsQWBw6M71FDfgJuR7n55d/7IV8MO+rpwQ=" + [mod."github.com/muesli/reflow"] + version = "v0.3.0" + hash = "sha256-Pou2ybE9SFSZG6YfZLVV1Eyfm+X4FuVpDPLxhpn47Cc=" [mod."github.com/muesli/termenv"] version = "v0.16.0" hash = "sha256-hGo275DJlyLtcifSLpWnk8jardOksdeX9lH4lBeE3gI=" @@ -605,6 +629,12 @@ cachePackages = ["cel.dev/expr", "cloud.google.com/go/compute/metadata", "dario. [mod."github.com/xo/terminfo"] version = "v0.0.0-20220910002029-abceb7e1c41e" hash = "sha256-GyCDxxMQhXA3Pi/TsWXpA8cX5akEoZV7CFx4RO3rARU=" + [mod."github.com/yuin/goldmark"] + version = "v1.7.13" + hash = "sha256-vBCxZrPYPc8x/nvAAv3Au59dCCyfS80Vw3/a9EXK7TE=" + [mod."github.com/yuin/goldmark-emoji"] + version = "v1.0.6" + hash = "sha256-+d6bZzOPE+JSFsZbQNZMCWE+n3jgcQnkPETVk47mxSY=" [mod."go.opentelemetry.io/auto/sdk"] version = "v1.2.1" hash = "sha256-73bFYhnxNf4SfeQ52ebnwOWywdQbqc9lWawCcSgofvE=" diff --git a/internal/style/dark.json b/internal/style/dark.json new file mode 100644 index 0000000..ab64251 --- /dev/null +++ b/internal/style/dark.json @@ -0,0 +1,157 @@ +{ + "document": { + "block_prefix": "\n", + "margin": 2 + }, + "block_quote": { + "indent": 1, + "indent_token": "│ " + }, + "paragraph": {}, + "list": { + "level_indent": 2 + }, + "heading": { + "block_suffix": "\n", + "color": "#35d0ba", + "bold": true + }, + "text": {}, + "strikethrough": { + "crossed_out": true + }, + "emph": { + "italic": true + }, + "strong": { + "bold": true + }, + "hr": { + "color": "#35d0ba", + "format": "\n--------\n" + }, + "item": { + "block_prefix": "• " + }, + "enumeration": { + "block_prefix": ". " + }, + "task": { + "ticked": "[✓] ", + "unticked": "[ ] " + }, + "link": { + "color": "#35d0ba", + "underline": true + }, + "link_text": { + "color": "#35d0ba", + "bold": true + }, + "image": { + "underline": true + }, + "image_text": { + "format": "Image: {{.text}} →" + }, + "code": { + "color": "#35d0ba" + }, + "code_block": { + "margin": 2, + "chroma": { + "text": {}, + "error": { + "color": "#f3807b", + "background_color": "#030724" + }, + "comment": { + "color": "#F7D186" + }, + "comment_preproc": { + "color": "#FF875F" + }, + "keyword": { + "color": "#00AAFF" + }, + "keyword_reserved": { + "color": "#FF5FD2" + }, + "keyword_namespace": { + "color": "#FF5F87" + }, + "keyword_type": { + "color": "#6E6ED8" + }, + "operator": { + "color": "#EF8080" + }, + "punctuation": { + "color": "#E8E8A8" + }, + "name": { + "color": "#C4C4C4" + }, + "name_builtin": { + "color": "#FF8EC7" + }, + "name_tag": { + "color": "#B083EA" + }, + "name_attribute": { + "color": "#7A7AE6" + }, + "name_class": { + "color": "#F1F1F1", + "underline": true, + "bold": true + }, + "name_constant": {}, + "name_decorator": { + "color": "#FFFF87" + }, + "name_exception": {}, + "name_function": { + "color": "#00D787" + }, + "name_other": {}, + "literal": {}, + "literal_number": { + "color": "#6EEFC0" + }, + "literal_date": {}, + "literal_string": { + "color": "#C69669" + }, + "literal_string_escape": { + "color": "#AFFFD7" + }, + "generic_deleted": { + "color": "#FD5B5B" + }, + "generic_emph": { + "italic": true + }, + "generic_inserted": { + "color": "#00D787" + }, + "generic_strong": { + "bold": true + }, + "generic_subheading": { + "color": "#777777" + }, + "background": { + "background_color": "#373737" + } + } + }, + "table": {}, + "definition_list": {}, + "definition_term": {}, + "definition_description": { + "block_prefix": "\n🠶 " + }, + "html_block": {}, + "html_span": {} +} diff --git a/internal/style/light.json b/internal/style/light.json new file mode 100644 index 0000000..09d4f4a --- /dev/null +++ b/internal/style/light.json @@ -0,0 +1,157 @@ +{ + "document": { + "block_prefix": "\n", + "margin": 2 + }, + "block_quote": { + "indent": 1, + "indent_token": "│ " + }, + "paragraph": {}, + "list": { + "level_indent": 2 + }, + "heading": { + "block_suffix": "\n", + "color": "#183d54", + "bold": true + }, + "text": {}, + "strikethrough": { + "crossed_out": true + }, + "emph": { + "italic": true + }, + "strong": { + "bold": true + }, + "hr": { + "color": "#183d54", + "format": "\n--------\n" + }, + "item": { + "block_prefix": "• " + }, + "enumeration": { + "block_prefix": ". " + }, + "task": { + "ticked": "[✓] ", + "unticked": "[ ] " + }, + "link": { + "color": "#183d54", + "underline": true + }, + "link_text": { + "color": "#183d54", + "bold": true + }, + "image": { + "underline": true + }, + "image_text": { + "format": "Image: {{.text}} →" + }, + "code": { + "color": "#183d54" + }, + "code_block": { + "margin": 2, + "chroma": { + "text": {}, + "error": { + "color": "#f3807b", + "background_color": "#030724" + }, + "comment": { + "color": "#183d54" + }, + "comment_preproc": { + "color": "#FF875F" + }, + "keyword": { + "color": "#279EFC" + }, + "keyword_reserved": { + "color": "#FF5FD2" + }, + "keyword_namespace": { + "color": "#FB406F" + }, + "keyword_type": { + "color": "#7049C2" + }, + "operator": { + "color": "#FF2626" + }, + "punctuation": { + "color": "#FA7878" + }, + "name": {}, + "name_builtin": { + "color": "#0A1BB1" + }, + "name_tag": { + "color": "#581290" + }, + "name_attribute": { + "color": "#8362CB" + }, + "name_class": { + "color": "#212121", + "underline": true, + "bold": true + }, + "name_constant": { + "color": "#581290" + }, + "name_decorator": { + "color": "#A3A322" + }, + "name_exception": {}, + "name_function": { + "color": "#019F57" + }, + "name_other": {}, + "literal": {}, + "literal_number": { + "color": "#22CCAE" + }, + "literal_date": {}, + "literal_string": { + "color": "#7E5B38" + }, + "literal_string_escape": { + "color": "#00AEAE" + }, + "generic_deleted": { + "color": "#FD5B5B" + }, + "generic_emph": { + "italic": true + }, + "generic_inserted": { + "color": "#00D787" + }, + "generic_strong": { + "bold": true + }, + "generic_subheading": { + "color": "#777777" + }, + "background": { + "background_color": "#373737" + } + } + }, + "table": {}, + "definition_list": {}, + "definition_term": {}, + "definition_description": { + "block_prefix": "\n🠶 " + }, + "html_block": {}, + "html_span": {} +} diff --git a/internal/style/style.go b/internal/style/style.go new file mode 100644 index 0000000..ad58c45 --- /dev/null +++ b/internal/style/style.go @@ -0,0 +1,70 @@ +/* +Copyright 2026 The Crossplane 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 style contains the shared style for the Crossplane CLI. +package style + +import ( + "os" + + "github.com/charmbracelet/glamour" + "github.com/charmbracelet/glamour/styles" + "github.com/charmbracelet/x/term" + "github.com/muesli/termenv" + + _ "embed" +) + +// RenderMarkdown formats markdown-formatted text for output to the terminal. If +// anything fails, the raw markdown is returned. +func RenderMarkdown(md string) string { + wrapWidth, _, _ := term.GetSize(os.Stdout.Fd()) + wrapWidth = min(wrapWidth, 120) + + tr, err := glamour.NewTermRenderer( + getStyleOpt(), + glamour.WithWordWrap(wrapWidth), + ) + if err != nil { + return md + } + + formatted, err := tr.Render(md) + if err != nil { + return md + } + + return formatted +} + +var ( + //go:embed light.json + lightStylesheet []byte + //go:embed dark.json + darkStylesheet []byte +) + +func getStyleOpt() glamour.TermRendererOption { + if !term.IsTerminal(os.Stdout.Fd()) { + return glamour.WithStandardStyle(styles.AsciiStyle) + } + + if termenv.HasDarkBackground() { + return glamour.WithStylesFromJSONBytes(darkStylesheet) + } + + return glamour.WithStylesFromJSONBytes(lightStylesheet) +}