cmd/doc: boiler plate and for inputs / outputs scanning
Signed-off-by: Sam Alba <sam.alba@gmail.com>
This commit is contained in:
parent
66929f8a63
commit
7b4421b9a0
144
cmd/dagger/cmd/doc.go
Normal file
144
cmd/dagger/cmd/doc.go
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"cuelang.org/go/cue"
|
||||||
|
"cuelang.org/go/cue/format"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
"go.dagger.io/dagger/cmd/dagger/cmd/common"
|
||||||
|
"go.dagger.io/dagger/cmd/dagger/logger"
|
||||||
|
"go.dagger.io/dagger/compiler"
|
||||||
|
"go.dagger.io/dagger/environment"
|
||||||
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
textFormat = "txt"
|
||||||
|
markdownFormat = "md"
|
||||||
|
)
|
||||||
|
|
||||||
|
var docCmd = &cobra.Command{
|
||||||
|
Use: "doc [PACKAGE | PATH]",
|
||||||
|
Short: "document a package",
|
||||||
|
Args: cobra.MaximumNArgs(1),
|
||||||
|
PreRun: func(cmd *cobra.Command, args []string) {
|
||||||
|
// Fix Viper bug for duplicate flags:
|
||||||
|
// https://github.com/spf13/viper/issues/233
|
||||||
|
if err := viper.BindPFlags(cmd.Flags()); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
lg := logger.New()
|
||||||
|
ctx := lg.WithContext(cmd.Context())
|
||||||
|
workspace := common.CurrentWorkspace(ctx)
|
||||||
|
st := common.CurrentEnvironmentState(ctx, workspace)
|
||||||
|
|
||||||
|
format := viper.GetString("output")
|
||||||
|
if format != textFormat && format != markdownFormat {
|
||||||
|
lg.Fatal().Msg("output must be either `txt` or `md`")
|
||||||
|
}
|
||||||
|
|
||||||
|
val, err := loadCode(args[0])
|
||||||
|
if err != nil {
|
||||||
|
lg.Fatal().Err(err).Msg("cannot compile code")
|
||||||
|
}
|
||||||
|
PrintDoc(ctx, val, format)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
docCmd.Flags().StringP("output", "o", textFormat, "Output format (txt|md)")
|
||||||
|
|
||||||
|
if err := viper.BindPFlags(docCmd.Flags()); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractComment(v cue.Value) string {
|
||||||
|
docs := []string{}
|
||||||
|
for _, c := range v.Doc() {
|
||||||
|
docs = append(docs, strings.TrimSpace(c.Text()))
|
||||||
|
}
|
||||||
|
doc := strings.Join(docs, " ")
|
||||||
|
|
||||||
|
lines := strings.Split(doc, "\n")
|
||||||
|
|
||||||
|
// Strip out FIXME, TODO, and INTERNAL comments
|
||||||
|
docs = []string{}
|
||||||
|
for _, line := range lines {
|
||||||
|
if strings.HasPrefix(line, "FIXME: ") ||
|
||||||
|
strings.HasPrefix(line, "TODO: ") ||
|
||||||
|
strings.HasPrefix(line, "INTERNAL: ") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
docs = append(docs, line)
|
||||||
|
}
|
||||||
|
return strings.Join(docs, " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractSpec(v cue.Value) string {
|
||||||
|
node := v.Source()
|
||||||
|
if node == nil {
|
||||||
|
return fmt.Sprintf("%v", v)
|
||||||
|
}
|
||||||
|
src, err := format.Node(node)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
space := regexp.MustCompile(`[\s\n]+`)
|
||||||
|
return strings.TrimSpace(
|
||||||
|
space.ReplaceAllString(string(src), " "),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func mdEscape(s string) string {
|
||||||
|
escape := []string{"|", "<", ">"}
|
||||||
|
for _, c := range escape {
|
||||||
|
s = strings.ReplaceAll(s, c, `\`+c)
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func terminalTrim(msg string) string {
|
||||||
|
// If we're not running on a terminal, return the whole string
|
||||||
|
size, _, err := terminal.GetSize(1)
|
||||||
|
if err != nil {
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, trim to fit half the terminal
|
||||||
|
size /= 2
|
||||||
|
for utf8.RuneCountInString(msg) > size {
|
||||||
|
msg = msg[0:len(msg)-4] + "…"
|
||||||
|
}
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadCode(path string) (*compiler.Value, error) {
|
||||||
|
src, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
val, err := compiler.Compile("", string(src))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func PrintDoc(ctx context.Context, val *compiler.Value, format string) {
|
||||||
|
lg := log.Ctx(ctx)
|
||||||
|
|
||||||
|
environment.ScanOutputs(ctx, val)
|
||||||
|
}
|
@ -46,6 +46,7 @@ func init() {
|
|||||||
input.Cmd,
|
input.Cmd,
|
||||||
output.Cmd,
|
output.Cmd,
|
||||||
versionCmd,
|
versionCmd,
|
||||||
|
docCmd,
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := viper.BindPFlags(rootCmd.PersistentFlags()); err != nil {
|
if err := viper.BindPFlags(rootCmd.PersistentFlags()); err != nil {
|
||||||
|
@ -320,7 +320,7 @@ func (e *Environment) ScanInputs(ctx context.Context, mergeUserInputs bool) ([]*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return scanInputs(ctx, src), nil
|
return ScanInputs(ctx, src), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Environment) ScanOutputs(ctx context.Context) ([]*compiler.Value, error) {
|
func (e *Environment) ScanOutputs(ctx context.Context) ([]*compiler.Value, error) {
|
||||||
@ -340,5 +340,5 @@ func (e *Environment) ScanOutputs(ctx context.Context) ([]*compiler.Value, error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return scanOutputs(ctx, src), nil
|
return ScanOutputs(ctx, src), nil
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ func isReference(val cue.Value) bool {
|
|||||||
return isRef(val)
|
return isRef(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
func scanInputs(ctx context.Context, value *compiler.Value) []*compiler.Value {
|
func ScanInputs(ctx context.Context, value *compiler.Value) []*compiler.Value {
|
||||||
lg := log.Ctx(ctx)
|
lg := log.Ctx(ctx)
|
||||||
inputs := []*compiler.Value{}
|
inputs := []*compiler.Value{}
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ func scanInputs(ctx context.Context, value *compiler.Value) []*compiler.Value {
|
|||||||
return inputs
|
return inputs
|
||||||
}
|
}
|
||||||
|
|
||||||
func scanOutputs(ctx context.Context, value *compiler.Value) []*compiler.Value {
|
func ScanOutputs(ctx context.Context, value *compiler.Value) []*compiler.Value {
|
||||||
lg := log.Ctx(ctx)
|
lg := log.Ctx(ctx)
|
||||||
inputs := []*compiler.Value{}
|
inputs := []*compiler.Value{}
|
||||||
|
|
||||||
|
1
go.mod
1
go.mod
@ -30,6 +30,7 @@ require (
|
|||||||
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
|
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
|
||||||
go.mozilla.org/sops/v3 v3.7.1
|
go.mozilla.org/sops/v3 v3.7.1
|
||||||
go.uber.org/atomic v1.7.0 // indirect
|
go.uber.org/atomic v1.7.0 // indirect
|
||||||
|
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
|
||||||
golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c // indirect
|
golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c // indirect
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1
|
||||||
|
Reference in New Issue
Block a user