cmd/doc: added support for text format
Signed-off-by: Sam Alba <sam.alba@gmail.com>
This commit is contained in:
parent
8c3c934f3c
commit
92d993f434
@ -4,8 +4,10 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"text/tabwriter"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"cuelang.org/go/cue"
|
"cuelang.org/go/cue"
|
||||||
@ -13,22 +15,24 @@ import (
|
|||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
"go.dagger.io/dagger/cmd/dagger/cmd/common"
|
||||||
"go.dagger.io/dagger/cmd/dagger/logger"
|
"go.dagger.io/dagger/cmd/dagger/logger"
|
||||||
"go.dagger.io/dagger/compiler"
|
"go.dagger.io/dagger/compiler"
|
||||||
"go.dagger.io/dagger/environment"
|
"go.dagger.io/dagger/environment"
|
||||||
"go.dagger.io/dagger/stdlib"
|
"go.dagger.io/dagger/stdlib"
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
"golang.org/x/term"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
textFormat = "txt"
|
textFormat = "txt"
|
||||||
markdownFormat = "md"
|
markdownFormat = "md"
|
||||||
|
textPadding = " "
|
||||||
)
|
)
|
||||||
|
|
||||||
var docCmd = &cobra.Command{
|
var docCmd = &cobra.Command{
|
||||||
Use: "doc [PACKAGE | PATH]",
|
Use: "doc [PACKAGE | PATH]",
|
||||||
Short: "document a package",
|
Short: "document a package",
|
||||||
Args: cobra.MaximumNArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
PreRun: func(cmd *cobra.Command, args []string) {
|
PreRun: func(cmd *cobra.Command, args []string) {
|
||||||
// Fix Viper bug for duplicate flags:
|
// Fix Viper bug for duplicate flags:
|
||||||
// https://github.com/spf13/viper/issues/233
|
// https://github.com/spf13/viper/issues/233
|
||||||
@ -63,28 +67,6 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
func extractSpec(v cue.Value) string {
|
||||||
node := v.Source()
|
node := v.Source()
|
||||||
if node == nil {
|
if node == nil {
|
||||||
@ -110,7 +92,7 @@ func mdEscape(s string) string {
|
|||||||
|
|
||||||
func terminalTrim(msg string) string {
|
func terminalTrim(msg string) string {
|
||||||
// If we're not running on a terminal, return the whole string
|
// If we're not running on a terminal, return the whole string
|
||||||
size, _, err := terminal.GetSize(1)
|
size, _, err := term.GetSize(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
@ -123,6 +105,11 @@ func terminalTrim(msg string) string {
|
|||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func formatLabel(name string, val *compiler.Value) string {
|
||||||
|
label := val.Path().String()
|
||||||
|
return strings.TrimPrefix(label, name+".")
|
||||||
|
}
|
||||||
|
|
||||||
func loadCode(packageName string) (*compiler.Value, error) {
|
func loadCode(packageName string) (*compiler.Value, error) {
|
||||||
sources := map[string]fs.FS{
|
sources := map[string]fs.FS{
|
||||||
stdlib.Path: stdlib.FS,
|
stdlib.Path: stdlib.FS,
|
||||||
@ -144,10 +131,15 @@ func PrintDoc(ctx context.Context, packageName string, val *compiler.Value, form
|
|||||||
lg.Fatal().Err(err).Msg("cannot get fields")
|
lg.Fatal().Err(err).Msg("cannot get fields")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
comment := common.ValueDocString(val)
|
||||||
|
|
||||||
// Print title
|
// Print title
|
||||||
switch format {
|
switch format {
|
||||||
case textFormat:
|
case textFormat:
|
||||||
fmt.Printf("Package:\t%s\n", packageName)
|
fmt.Printf("Package %s\n", packageName)
|
||||||
|
if comment != "" {
|
||||||
|
fmt.Printf("\n%s\n", comment)
|
||||||
|
}
|
||||||
case markdownFormat:
|
case markdownFormat:
|
||||||
importPath := strings.Split(packageName, "/")
|
importPath := strings.Split(packageName, "/")
|
||||||
switch {
|
switch {
|
||||||
@ -158,6 +150,9 @@ func PrintDoc(ctx context.Context, packageName string, val *compiler.Value, form
|
|||||||
default:
|
default:
|
||||||
fmt.Printf("## %s\n", packageName)
|
fmt.Printf("## %s\n", packageName)
|
||||||
}
|
}
|
||||||
|
if comment != "" {
|
||||||
|
fmt.Printf("\n%s\n", comment)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, field := range fields {
|
for _, field := range fields {
|
||||||
@ -171,22 +166,58 @@ func PrintDoc(ctx context.Context, packageName string, val *compiler.Value, form
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Package name + comment
|
||||||
|
comment := common.ValueDocString(v)
|
||||||
switch format {
|
switch format {
|
||||||
case textFormat:
|
case textFormat:
|
||||||
comment := extractComment(v.Cue())
|
fmt.Printf("\n%s\n\n%s%s\n", name, textPadding, comment)
|
||||||
if comment != "" {
|
|
||||||
comment = fmt.Sprintf(": %s", comment)
|
|
||||||
}
|
|
||||||
fmt.Printf("\n=> %s%s\n", name, comment)
|
|
||||||
case markdownFormat:
|
case markdownFormat:
|
||||||
comment := extractComment(v.Cue())
|
|
||||||
if comment != "" {
|
if comment != "" {
|
||||||
comment = fmt.Sprintf("\n\n%s", comment)
|
comment = fmt.Sprintf("\n\n%s", comment)
|
||||||
}
|
}
|
||||||
fmt.Printf("\n#### %s%s\n\n", name, mdEscape(comment))
|
fmt.Printf("\n#### %s%s\n\n", name, mdEscape(comment))
|
||||||
fmt.Printf("##### Fields\n\n")
|
fmt.Printf("##### Fields\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Package inputs
|
||||||
|
inp := environment.ScanInputs(ctx, v)
|
||||||
|
switch format {
|
||||||
|
case textFormat:
|
||||||
|
if len(inp) == 0 {
|
||||||
|
fmt.Printf("\n%sInputs: none\n", textPadding)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
w := tabwriter.NewWriter(os.Stdout, 0, 4, len(textPadding), ' ', 0)
|
||||||
|
fmt.Printf("\n%sInputs:\n", textPadding)
|
||||||
|
for _, i := range inp {
|
||||||
|
docStr := terminalTrim(common.ValueDocString(i))
|
||||||
|
fmt.Fprintf(w, "\t\t%s\t%s\t%s\n",
|
||||||
|
formatLabel(name, i), common.FormatValue(i), docStr)
|
||||||
|
}
|
||||||
|
w.Flush()
|
||||||
|
case markdownFormat:
|
||||||
|
// todo
|
||||||
|
}
|
||||||
|
|
||||||
|
// Package outputs
|
||||||
|
out := environment.ScanOutputs(ctx, v)
|
||||||
|
switch format {
|
||||||
|
case textFormat:
|
||||||
|
if len(out) == 0 {
|
||||||
|
fmt.Printf("\n%sOutputs: none\n", textPadding)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
w := tabwriter.NewWriter(os.Stdout, 0, 4, len(textPadding), ' ', 0)
|
||||||
|
fmt.Printf("\n%sOutputs:\n", textPadding)
|
||||||
|
for _, o := range out {
|
||||||
|
docStr := terminalTrim(common.ValueDocString(o))
|
||||||
|
fmt.Fprintf(w, "\t\t%s\t%s\t%s\n",
|
||||||
|
formatLabel(name, o), common.FormatValue(o), docStr)
|
||||||
|
}
|
||||||
|
w.Flush()
|
||||||
|
case markdownFormat:
|
||||||
|
// todo
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
environment.ScanOutputs(ctx, val)
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user