Skip to content

Commit

Permalink
Merge pull request #134 from rsteube/run
Browse files Browse the repository at this point in the history
support runnable specs
  • Loading branch information
rsteube authored Feb 17, 2023
2 parents b756c49 + b433b69 commit 69024d9
Show file tree
Hide file tree
Showing 7 changed files with 333 additions and 90 deletions.
29 changes: 16 additions & 13 deletions action.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ import (
"gopkg.in/yaml.v3"
)

// static value or macro
type action string
type (
// static or dynamic value (macro)
value string
action []value
)

func (action) JSONSchema() *jsonschema.Schema {
func (value) JSONSchema() *jsonschema.Schema {
sortedNames := make([]string, 0, len(macros))
for name := range macros {
sortedNames = append(sortedNames, name)
Expand Down Expand Up @@ -80,19 +83,19 @@ func ActionSpec(path string) carapace.Action {
})
}

func parseAction(cmd *cobra.Command, arr []action) carapace.Action {
if !cmd.DisableFlagParsing {
for _, entry := range arr {
if strings.HasPrefix(string(entry), "$") {
macro := strings.SplitN(strings.TrimPrefix(string(entry), "$"), "(", 2)[0]
if m, ok := macros[macro]; ok && m.disableFlagParsing {
cmd.DisableFlagParsing = true // implicitly disable flag parsing
break
}
func (a action) disableFlagParsing() bool {
for _, value := range a {
if strings.HasPrefix(string(value), "$") {
macro := strings.SplitN(strings.TrimPrefix(string(value), "$"), "(", 2)[0]
if m, ok := macros[macro]; ok && m.disableFlagParsing {
return true
}
}
}
return false
}

func (a action) parse(cmd *cobra.Command) carapace.Action {
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
// TODO yuck - where to set thes best?
for index, arg := range c.Args {
Expand All @@ -110,7 +113,7 @@ func parseAction(cmd *cobra.Command, arr []action) carapace.Action {
})

vals := make([]string, 0)
for _, elem := range arr {
for _, elem := range a {
if elemSubst, err := c.Envsubst(string(elem)); err != nil {
batch = append(batch, carapace.ActionMessage("%v: %#v", err.Error(), elem))
} else if strings.HasPrefix(elemSubst, "$") { // macro
Expand Down
126 changes: 75 additions & 51 deletions cmd/carapace-spec/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"bytes"
"errors"
"fmt"
"io"
"os"
Expand Down Expand Up @@ -34,83 +35,106 @@ var rootCmd = &cobra.Command{
DisableDefaultCmd: true,
},
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) > 0 && args[0] == "-h" || args[0] == "--help" {
switch args[0] {
case "-h", "--help":
cmd.Help()
return nil
}

abs, err := filepath.Abs(args[0])
if err != nil {
return err
}

content, err := os.ReadFile(abs)
if err != nil {
return err
}

var specCmd spec.Command
if err := yaml.Unmarshal(content, &specCmd); err != nil {
return err
}

if flag := cmd.Flag("scrape"); flag != nil && flag.Changed {
specCmd.Scrape()
} else {
case "--scrape":
if len(args) < 2 {
return errors.New("flag needs an argument: --scrape")
}
command, err := loadSpec(args[1])
if err != nil {
return err
}
command.Scrape()
case "--run":
command, err := loadSpec(args[1])
if err != nil {
return err
}
cobraCmd := command.ToCobra()
cobraCmd.SetArgs(args[2:])
cobraCmd.Execute()
default:
abs, err := filepath.Abs(args[0])
if err != nil {
return err
}
specCmd, err := loadSpec(abs)
if err != nil {
return err
}
bridgeCompletion(specCmd.ToCobra(), abs, args[1:]...)
}
return nil
},
}

func loadSpec(path string) (*spec.Command, error) {
abs, err := filepath.Abs(path)
if err != nil {
return nil, err
}

content, err := os.ReadFile(abs)
if err != nil {
return nil, err
}

var specCmd spec.Command
if err := yaml.Unmarshal(content, &specCmd); err != nil {
return nil, err
}
return &specCmd, nil
}

func Execute() error {
return rootCmd.Execute()
}
func init() {
rootCmd.Flags().Bool("scrape", false, "scrape to go code")

if len(os.Args) < 2 || os.Args[1] == "--scrape" {
rootCmd.DisableFlagParsing = false
}
rootCmd.Flags().Bool("run", false, "run with given args")

carapace.Gen(rootCmd).PositionalCompletion(
carapace.ActionFiles(".yaml"),
)

carapace.Gen(rootCmd).PositionalAnyCompletion(
carapace.ActionCallback(func(c carapace.Context) carapace.Action {
if rootCmd.Flag("scrape").Changed {
switch {
case c.Args[0] == "--run":
if len(c.Args) > 1 {
path := c.Args[1]
c.Args = c.Args[2:]
return spec.ActionSpec(path).Invoke(c).ToA()
}
return carapace.ActionFiles(".yaml")

case c.Args[0] == "--scrape" && len(c.Args) == 1:
return carapace.ActionFiles(".yaml")

case !strings.HasPrefix(c.Args[0], "-"):
path := c.Args[0]
if len(c.Args) < 3 {
c.Args[0] = "_carapace"
} else {
c.Args = c.Args[3:]
}
return spec.ActionSpec(path).Invoke(c).ToA()

default:
return carapace.ActionValues()
}

abs, err := filepath.Abs(c.Args[0])
if err != nil {
return carapace.ActionMessage(err.Error())
}

content, err := os.ReadFile(abs)
if err != nil {
return carapace.ActionMessage(err.Error())
}

var specCmd spec.Command
if err := yaml.Unmarshal(content, &specCmd); err != nil {
return carapace.ActionMessage(err.Error())
}

if len(c.Args) > 2 {
c.Args = c.Args[3:]
} else {
c.Args[0] = "_carapace"
}

return carapace.ActionExecute(specCmd.ToCobra()).Invoke(c).ToA()
}),
)

carapace.Gen(rootCmd).PreRun(func(cmd *cobra.Command, args []string) {
if len(args) < 2 || args[0] == "--scrape" {
switch len(args) {
case 0, 1:
cmd.DisableFlagParsing = false

default:
cmd.Flags().Parse(args[:1]) // TODO unnecessary
}
})
}
Expand Down
Loading

0 comments on commit 69024d9

Please sign in to comment.