feat: add env command (#45)

* feat: add env command

* fix: add pad

* fix: hostname separator

* feat: remove enforced $H

* refactor: rename pkg to internal

* revert: hostname separation
This commit is contained in:
Kevin Franklin Kim 2023-11-23 12:19:19 +01:00 committed by GitHub
parent 71afc97283
commit 8929c62a64
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 138 additions and 18 deletions

View File

@ -1,6 +1,6 @@
module {{ .module }}/posh module {{ .module }}/posh
go 1.19 go 1.21
replace ( replace (
github.com/c-bata/go-prompt v0.2.6 => github.com/franklinkim/go-prompt v0.2.7-0.20210427061716-a8f4995d7aa5 github.com/c-bata/go-prompt v0.2.6 => github.com/franklinkim/go-prompt v0.2.7-0.20210427061716-a8f4995d7aa5

View File

@ -3,7 +3,7 @@ package command
import ( import (
"context" "context"
"{{.module}}/posh/pkg/config" "{{.module}}/posh/internal/config"
"github.com/foomo/posh/pkg/log" "github.com/foomo/posh/pkg/log"
"github.com/foomo/posh/pkg/readline" "github.com/foomo/posh/pkg/readline"
"github.com/spf13/viper" "github.com/spf13/viper"

View File

@ -1,4 +1,4 @@
package pkg package internal
import ( import (
"context" "context"
@ -15,7 +15,7 @@ import (
"github.com/foomo/posh/pkg/prompt/history" "github.com/foomo/posh/pkg/prompt/history"
"github.com/foomo/posh/pkg/readline" "github.com/foomo/posh/pkg/readline"
"github.com/foomo/posh/pkg/require" "github.com/foomo/posh/pkg/require"
pkgcommand "{{.module}}/posh/pkg/command" icommand "{{.module}}/posh/internal/command"
) )
type Plugin struct { type Plugin struct {
@ -39,8 +39,8 @@ func New(l log.Logger) (plugin.Plugin, error) {
// Welcome // Welcome
inst.commands.MustAdd( inst.commands.MustAdd(
pkgcommand.NewWelcome(l, icommand.NewWelcome(l,
pkgcommand.WelcomeWithConfigKey("welcome"), icommand.WelcomeWithConfigKey("welcome"),
), ),
) )

View File

@ -1,12 +1,12 @@
package main package main
import ( import (
"{{.module}}/posh/pkg" "{{.module}}/posh/internal"
"github.com/foomo/posh/cmd" "github.com/foomo/posh/cmd"
) )
func init() { func init() {
cmd.Init(pkg.New) cmd.Init(internal.New)
} }
func main() { func main() {

View File

@ -33,11 +33,11 @@ func NewCache(l log.Logger, cache cache.Cache) *Cache {
} }
inst.tree = tree.New(&tree.Node{ inst.tree = tree.New(&tree.Node{
Name: "cache", Name: "cache",
Description: "manage the internal cache", Description: "Manage the internal cache",
Nodes: tree.Nodes{ Nodes: tree.Nodes{
{ {
Name: "clear", Name: "clear",
Description: "clear caches", Description: "Clear caches",
Args: tree.Args{ Args: tree.Args{
{ {
Name: "Namespace", Name: "Namespace",
@ -53,7 +53,7 @@ func NewCache(l log.Logger, cache cache.Cache) *Cache {
}, },
{ {
Name: "list", Name: "list",
Description: "list all caches", Description: "List all caches",
Execute: inst.list, Execute: inst.list,
}, },
}, },

111
pkg/command/env.go Normal file
View File

@ -0,0 +1,111 @@
package command
import (
"context"
"os"
"strings"
"github.com/foomo/posh/pkg/command/tree"
"github.com/foomo/posh/pkg/log"
"github.com/foomo/posh/pkg/prompt/goprompt"
"github.com/foomo/posh/pkg/readline"
"github.com/pterm/pterm"
)
type Env struct {
l log.Logger
tree tree.Root
}
// ------------------------------------------------------------------------------------------------
// ~ Constructor
// ------------------------------------------------------------------------------------------------
func NewEnv(l log.Logger) *Env {
inst := &Env{
l: l,
}
inst.tree = tree.New(&tree.Node{
Name: "env",
Description: "Manage internal environment variables",
Nodes: tree.Nodes{
{
Name: "list",
Description: "List all environment variables",
Execute: inst.list,
},
{
Name: "set",
Description: "Set an internal environment variable",
Args: tree.Args{
{
Name: "Key",
Description: "Key of the environment variable.",
},
{
Name: "Value",
Optional: true,
Description: "Value of the environment variable.",
},
},
Execute: inst.set,
},
{
Name: "unset",
Description: "Unset an environment variable",
Args: tree.Args{
{
Name: "Key",
Description: "Key of the environment variable.",
},
},
Execute: inst.unset,
},
},
})
return inst
}
// ------------------------------------------------------------------------------------------------
// ~ Public methods
// ------------------------------------------------------------------------------------------------
func (c *Env) Name() string {
return c.tree.Node().Name
}
func (c *Env) Description() string {
return c.tree.Node().Description
}
func (c *Env) Complete(ctx context.Context, r *readline.Readline) []goprompt.Suggest {
return c.tree.Complete(ctx, r)
}
func (c *Env) Execute(ctx context.Context, r *readline.Readline) error {
return c.tree.Execute(ctx, r)
}
func (c *Env) Help(ctx context.Context, r *readline.Readline) string {
return c.tree.Help(ctx, r)
}
// ------------------------------------------------------------------------------------------------
// ~ Private methods
// ------------------------------------------------------------------------------------------------
func (c *Env) set(ctx context.Context, r *readline.Readline) error {
return os.Setenv(r.Args().At(0), r.Args().AtDefault(1, ""))
}
func (c *Env) unset(ctx context.Context, r *readline.Readline) error {
return os.Unsetenv(r.Args().At(0))
}
func (c *Env) list(ctx context.Context, r *readline.Readline) error {
data := pterm.TableData{{"Name", "Value"}}
for _, s := range os.Environ() {
data = append(data, strings.SplitN(s, "=", 2))
}
return pterm.DefaultTable.WithHasHeader(true).WithData(data).Render()
}

View File

@ -134,19 +134,20 @@ func (c *Node) find(ctx context.Context, r *readline.Readline, i int) (*Node, in
} }
func (c *Node) help(ctx context.Context, r *readline.Readline) string { func (c *Node) help(ctx context.Context, r *readline.Readline) string {
pad := " "
ret := c.Description ret := c.Description
if len(c.Nodes) > 0 { if len(c.Nodes) > 0 {
ret += "\n\nUsage:\n" ret += "\n\nUsage:\n"
ret += " " + c.Name + " [command]" ret += pad + c.Name + " [command]"
ret += "\n\nAvailable Commands:\n" ret += "\n\nAvailable Commands:\n"
for _, node := range c.Nodes { for _, node := range c.Nodes {
ret += " " + xstrings.PadEnd(node.Name, " ", 30) + node.Description + "\n" ret += pad + xstrings.PadEnd(node.Name, " ", 30) + node.Description + "\n"
} }
} else { } else {
ret += "\n\nUsage:\n" ret += "\n\nUsage:\n"
ret += " " + c.Name ret += pad + c.Name
for _, arg := range c.Args { for _, arg := range c.Args {
ret += " " ret += " "
@ -167,7 +168,7 @@ func (c *Node) help(ctx context.Context, r *readline.Readline) string {
if len(c.Args) > 0 { if len(c.Args) > 0 {
ret += "\n\nArguments:\n" ret += "\n\nArguments:\n"
for _, arg := range c.Args { for _, arg := range c.Args {
ret += " " + xstrings.PadEnd(arg.Name, " ", 30) + arg.Description + "\n" ret += pad + xstrings.PadEnd(arg.Name, " ", 30) + arg.Description + "\n"
} }
} }

View File

@ -31,7 +31,7 @@ func TestRoot(t *testing.T) {
r := tree.New(&tree.Node{ r := tree.New(&tree.Node{
Name: "root", Name: "root",
Description: "root tree", Description: "Root tree",
Execute: func(ctx context.Context, r *readline.Readline) error { Execute: func(ctx context.Context, r *readline.Readline) error {
return ErrRoot return ErrRoot
}, },

View File

@ -11,7 +11,7 @@ func DefaultFlair(title string) error {
pterm.FgGray.Println() pterm.FgGray.Println()
if err := pterm.DefaultBigText.WithLetters( if err := pterm.DefaultBigText.WithLetters(
putils.LettersFromStringWithStyle(strings.ToUpper(title), pterm.NewStyle(pterm.FgCyan)), putils.LettersFromStringWithStyle(strings.ToUpper(title), pterm.NewStyle(pterm.FgCyan)),
putils.LettersFromStringWithStyle("$H", pterm.NewStyle(pterm.FgGreen))). ).
Render(); err != nil { Render(); err != nil {
return err return err
} }

View File

@ -289,7 +289,7 @@ func (s *Prompt) complete(d prompt.Document) []prompt.Suggest {
if s.readline.IsModeDefault() && s.readline.Args().LenIs(0) { if s.readline.IsModeDefault() && s.readline.Args().LenIs(0) {
var suggests []prompt.Suggest var suggests []prompt.Suggest
for key, value := range s.aliases { for key, value := range s.aliases {
suggests = append(suggests, prompt.Suggest{Text: key, Description: "alias: " + value}) suggests = append(suggests, prompt.Suggest{Text: key, Description: "Alias: " + value})
} }
for _, inst := range s.Commands().List() { for _, inst := range s.Commands().List() {
suggests = append(suggests, prompt.Suggest{Text: inst.Name(), Description: inst.Description()}) suggests = append(suggests, prompt.Suggest{Text: inst.Name(), Description: inst.Description()})

View File

@ -14,6 +14,14 @@ func (a Args) At(v int) string {
} }
} }
func (a Args) AtDefault(v int, fallback string) string {
if a.HasIndex(v) {
return a[v]
} else {
return fallback
}
}
func (a Args) Shift() (string, Args) { func (a Args) Shift() (string, Args) {
if a.HasIndex(0) { if a.HasIndex(0) {
return a[0], a[1:] return a[0], a[1:]