Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spec: documentation #998

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions internal/spec/command.go

This file was deleted.

49 changes: 49 additions & 0 deletions internal/spec/command/command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package command

type Command struct {
Name string `yaml:"name" json:"name" jsonschema_description:"Name of the command"`
Aliases []string `yaml:"aliases,omitempty" json:"aliases,omitempty" jsonschema_description:"Aliases of the command"`
Description string `yaml:"description,omitempty" json:"description,omitempty" jsonschema_description:"Description of the command"`
Group string `yaml:"group,omitempty" json:"group,omitempty" jsonschema_description:"Group of the command"`
Hidden bool `yaml:"hidden,omitempty" json:"hidden,omitempty" jsonschema_description:"Hidden state of the command"`
Parsing Parsing `yaml:"parsing,omitempty" json:"parsing,omitempty" jsonschema_description:"Flag parsing mode of the command" jsonschema:"enum=interspersed,enum=non-interspersed,enum=disabled"`

Flags map[string]string `yaml:"flags,omitempty" json:"flags,omitempty" jsonschema_description:"Flags of the command with their description"`
PersistentFlags map[string]string `yaml:"persistentflags,omitempty" json:"persistentflags,omitempty" jsonschema_description:"Persistent flags of the command with their description"`
ExclusiveFlags [][]string `yaml:"exclusiveflags,omitempty" json:"exclusiveflags,omitempty" jsonschema_description:"Flags that are mutually exclusive"`
Run string `yaml:"run,omitempty" json:"run,omitempty" jsonschema_description:"Command or script to execute in runnable mode"`
Completion struct {
Flag map[string][]string `yaml:"flag,omitempty" json:"flag,omitempty" jsonschema_description:"Flag completion"`
Positional [][]string `yaml:"positional,omitempty" json:"positional,omitempty" jsonschema_description:"Positional completion"`
PositionalAny []string `yaml:"positionalany,omitempty" json:"positionalany,omitempty" jsonschema_description:"Positional completion for every other position"`
Dash [][]string `yaml:"dash,omitempty" json:"dash,omitempty" jsonschema_description:"Dash completion"`
DashAny []string `yaml:"dashany,omitempty" json:"dashany,omitempty" jsonschema_description:"Dash completion of every other position"`
} `yaml:"completion,omitempty" json:"completion,omitempty" jsonschema_description:"Completion definition"`
Commands []Command `yaml:"commands,omitempty" json:"commands,omitempty" jsonschema_description:"Subcommands of the command"`

Documentation struct {
Command string `yaml:"command,omitempty" json:"command,omitempty" jsonschema_description:"Documentation of the command"`
Flag map[string]string `yaml:"flag,omitempty" json:"flag,omitempty" jsonschema_description:"Documentation of flags"`
Positional []string `yaml:"positional,omitempty" json:"positional,omitempty" jsonschema_description:"Documentation of positional arguments"`
PositionalAny string `yaml:"positionalany,omitempty" json:"positionalany,omitempty" jsonschema_description:"Documentation of other positional arguments"`
Dash []string `yaml:"dash,omitempty" json:"dash,omitempty" jsonschema_description:"Documentation of dash arguments"`
DashAny string `yaml:"dashany,omitempty" json:"dashany,omitempty" jsonschema_description:"Documentation of other dash arguments"`
} `yaml:"documentation,omitempty" json:"documentation,omitempty" jsonschema_description:"Documentation"`
Examples map[string]string `yaml:"examples,omitempty" json:"examples,omitempty" jsonschema_description:"Examples"`
}

func (c *Command) AddFlag(f Flag) {
switch {
case f.Persistent:
if c.PersistentFlags == nil {
c.PersistentFlags = make(map[string]string)
}
c.PersistentFlags[f.format()] = f.Usage

default:
if c.Flags == nil {
c.Flags = make(map[string]string)
}
c.Flags[f.format()] = f.Usage
}
}
49 changes: 49 additions & 0 deletions internal/spec/command/flag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package command

type Flag struct {
Longhand string
Shorthand string
Usage string
Repeatable bool
Optarg bool
Value bool
Hidden bool
Required bool
Persistent bool
}

func (f Flag) format() string {
var s string

if f.Shorthand != "" {
s += f.Shorthand
if f.Longhand != "" {
s += ", "
}
}

if f.Longhand != "" {
s += f.Longhand
}

switch {
case f.Optarg:
s += "?"
case f.Value:
s += "="
}

if f.Repeatable {
s += "*"
}

if f.Required {
s += "!"
}

if f.Hidden {
s += "&"
}

return s
}
10 changes: 10 additions & 0 deletions internal/spec/command/parsing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package command

type Parsing string

const (
DEFAULT Parsing = "" // INTERSPERSED but allows implicit changes
INTERSPERSED Parsing = "interspersed" // mixed flags and positional arguments
NON_INTERSPERSED Parsing = "non-interspersed" // flag parsing stopped after first positional argument
DISABLED Parsing = "disabled" // flag parsing disabled
)
13 changes: 8 additions & 5 deletions internal/spec/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,28 @@ package spec

import (
"github.com/rsteube/carapace/internal/pflagfork"
"github.com/rsteube/carapace/internal/spec/command"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"gopkg.in/yaml.v3"
)

// Spec generates the spec file.
func Spec(cmd *cobra.Command) string {
m, _ := yaml.Marshal(command(cmd))
m, _ := yaml.Marshal(genCommand(cmd))
return "# yaml-language-server: $schema=https://carapace.sh/schemas/command.json\n" + string(m)
}

func command(cmd *cobra.Command) Command {
c := Command{
func genCommand(cmd *cobra.Command) command.Command {
c := command.Command{
Name: cmd.Use,
Description: cmd.Short,
Aliases: cmd.Aliases,
Group: cmd.GroupID,
Hidden: cmd.Hidden,
Flags: make(map[string]string),
PersistentFlags: make(map[string]string),
Commands: make([]Command, 0),
Commands: make([]command.Command, 0),
}

// TODO mutually exclusive flags
Expand All @@ -46,9 +47,11 @@ func command(cmd *cobra.Command) Command {

for _, subcmd := range cmd.Commands() {
if subcmd.Name() != "_carapace" && subcmd.Deprecated == "" {
c.Commands = append(c.Commands, command(subcmd))
c.Commands = append(c.Commands, genCommand(subcmd))
}
}

c.Documentation.Command = cmd.Long

return c
}
Loading