From 9f4a1e1fc47cdccec0949ba018f369643c1506dd Mon Sep 17 00:00:00 2001 From: rsteube Date: Thu, 3 Nov 2022 18:13:55 +0100 Subject: [PATCH] added ttyd --- completers/ttyd_completer/cmd/root.go | 69 +++++++++++++++++++++++++++ completers/ttyd_completer/main.go | 7 +++ pkg/util/embed/embed.go | 67 ++++++++++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 completers/ttyd_completer/cmd/root.go create mode 100644 completers/ttyd_completer/main.go create mode 100644 pkg/util/embed/embed.go diff --git a/completers/ttyd_completer/cmd/root.go b/completers/ttyd_completer/cmd/root.go new file mode 100644 index 0000000000..98a06cd396 --- /dev/null +++ b/completers/ttyd_completer/cmd/root.go @@ -0,0 +1,69 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/rsteube/carapace-bin/pkg/actions/net" + "github.com/rsteube/carapace-bin/pkg/actions/os" + "github.com/rsteube/carapace-bin/pkg/actions/ps" + "github.com/rsteube/carapace-bin/pkg/util/embed" + "github.com/spf13/cobra" +) + +var rootCmd = &cobra.Command{ + Use: "ttyd", + Short: "ttyd is a tool for sharing terminal over the web", + Long: "https://github.com/tsl0922/ttyd", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func Execute() error { + return rootCmd.Execute() +} +func init() { + carapace.Gen(rootCmd).Standalone() + + rootCmd.Flags().StringP("auth-header", "H", "", "HTTP Header name for auth proxy") + rootCmd.Flags().StringP("base-path", "b", "", "Expected base path for requests coming from a reverse proxy") + rootCmd.Flags().BoolP("browser", "B", false, "Open terminal with the default system browser") + rootCmd.Flags().BoolP("check-origin", "O", false, "Do not allow websocket connection from different origin") + rootCmd.Flags().StringP("client-option", "t", "", "Send option to client") + rootCmd.Flags().StringP("credential", "c", "", "Credential for basic authentication") + rootCmd.Flags().StringP("cwd", "w", "", "Working directory to be set for the child program") + rootCmd.Flags().StringP("debug", "d", "", "Set log level") + rootCmd.Flags().StringP("gid", "g", "", "Group id to run with") + rootCmd.Flags().BoolP("help", "h", false, "Print this text and exit") + rootCmd.Flags().StringP("index", "I", "", "Custom index.html path") + rootCmd.Flags().StringP("interface", "i", "", "Network interface to bind") + rootCmd.Flags().BoolP("ipv6", "6", false, "Enable IPv6 support") + rootCmd.Flags().StringP("max-clients", "m", "", "Maximum clients to support") + rootCmd.Flags().BoolP("once", "o", false, "Accept only one client and exit on disconnection") + rootCmd.Flags().StringP("ping-interval", "P", "", "Websocket ping interval(sec)") + rootCmd.Flags().StringP("port", "p", "", "Port to listen") + rootCmd.Flags().BoolP("readonly", "R", false, "Do not allow clients to write to the TTY") + rootCmd.Flags().StringP("signal", "s", "", "Signal to send to the command when exit it") + rootCmd.Flags().BoolP("ssl", "S", false, "Enable SSL") + rootCmd.Flags().StringP("ssl-ca", "A", "", "SSL CA file path for client certificate verification") + rootCmd.Flags().StringP("ssl-cert", "C", "", "SSL certificate file path") + rootCmd.Flags().StringP("ssl-key", "K", "", "SSL key file path") + rootCmd.Flags().StringP("terminal-type", "T", "", "Terminal type to report") + rootCmd.Flags().StringP("uid", "u", "", "User id to run with") + rootCmd.Flags().StringP("url-arg", "a", "", "Allow client to send command line arguments in URL") + rootCmd.Flags().BoolP("version", "v", false, "Print the version and exit") + + carapace.Gen(rootCmd).FlagCompletion(carapace.ActionMap{ + "cwd": carapace.ActionDirectories(), + "gid": os.ActionGroups(), + "interface": carapace.Batch( + net.ActionDevices(net.IncludedDevices{Ethernet: true, Wifi: true}), + carapace.ActionFiles(), + ).ToA(), + "port": net.ActionPorts(), + "signal": ps.ActionKillSignals(), + "ssl-ca": carapace.ActionFiles(), + "ssl-cert": carapace.ActionFiles(), + "ssl-key": carapace.ActionFiles(), + "uid": os.ActionUsers(), + }) + + embed.EmbedCarapaceBin(rootCmd) +} diff --git a/completers/ttyd_completer/main.go b/completers/ttyd_completer/main.go new file mode 100644 index 0000000000..ad1620a6a7 --- /dev/null +++ b/completers/ttyd_completer/main.go @@ -0,0 +1,7 @@ +package main + +import "github.com/rsteube/carapace-bin/completers/ttyd_completer/cmd" + +func main() { + cmd.Execute() +} diff --git a/pkg/util/embed/embed.go b/pkg/util/embed/embed.go new file mode 100644 index 0000000000..d0ba137f87 --- /dev/null +++ b/pkg/util/embed/embed.go @@ -0,0 +1,67 @@ +package embed + +import ( + "github.com/rsteube/carapace" + "github.com/rsteube/carapace-bin/pkg/actions/bridge" + "github.com/rsteube/carapace-bin/pkg/actions/os" + "github.com/spf13/cobra" + "github.com/spf13/pflag" +) + +type stringValue string + +func (s *stringValue) Set(val string) error { + return nil +} +func (s *stringValue) Type() string { + return "string" +} + +func (s *stringValue) String() string { return string(*s) } + +// EmbedCarapaceBin **EXPERIMENTAL** adds a two-pass positional completion for commands like `sudo [CMD] [ARGS]...` +func EmbedCarapaceBin(cmd *cobra.Command) { + carapace.Gen(cmd).PositionalCompletion( + carapace.Batch( + os.ActionPathExecutables(), + carapace.ActionFiles(), + ).ToA(), + ) + + carapace.Gen(cmd).PreRun(func(cmd *cobra.Command, args []string) { + flags := pflag.NewFlagSet("copy", pflag.ContinueOnError) + flags.ParseErrorsWhitelist = pflag.ParseErrorsWhitelist{ + UnknownFlags: true, + } + var value stringValue + cmd.Flags().VisitAll(func(f *pflag.Flag) { + flags.AddFlag(&pflag.Flag{ + Name: f.Name, + Shorthand: f.Shorthand, + Style: f.Style, + Usage: f.Usage, + Value: &value, + DefValue: f.DefValue, + Changed: f.Changed, + NoOptDefVal: f.NoOptDefVal, + Deprecated: f.Deprecated, + Hidden: f.Hidden, + ShorthandDeprecated: f.ShorthandDeprecated, + Annotations: f.Annotations, + }) + }) + + if err := flags.Parse(args); err == nil && len(flags.Args()) > 1 { + subCmd := &cobra.Command{ + Use: flags.Args()[0], + Run: func(cmd *cobra.Command, args []string) {}, + DisableFlagParsing: true, + } + cmd.AddCommand(subCmd) + + carapace.Gen(subCmd).PositionalAnyCompletion( + bridge.ActionCarapaceBin(flags.Args()[0]), + ) + } + }) +}