github.com/onsi/ginkgo@v1.16.6-0.20211118180735-4e1925ba4c95/ginkgo/outline/outline_command.go (about)

     1  package outline
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"go/parser"
     7  	"go/token"
     8  	"os"
     9  
    10  	"github.com/onsi/ginkgo/ginkgo/command"
    11  	"github.com/onsi/ginkgo/types"
    12  )
    13  
    14  const (
    15  	// indentWidth is the width used by the 'indent' output
    16  	indentWidth = 4
    17  	// stdinAlias is a portable alias for stdin. This convention is used in
    18  	// other CLIs, e.g., kubectl.
    19  	stdinAlias   = "-"
    20  	usageCommand = "ginkgo outline <filename>"
    21  )
    22  
    23  type outlineConfig struct {
    24  	Format string
    25  }
    26  
    27  func BuildOutlineCommand() command.Command {
    28  	conf := outlineConfig{
    29  		Format: "csv",
    30  	}
    31  	flags, err := types.NewGinkgoFlagSet(
    32  		types.GinkgoFlags{
    33  			{Name: "format", KeyPath: "Format",
    34  				Usage:             "Format of outline",
    35  				UsageArgument:     "one of 'csv', 'indent', or 'json'",
    36  				UsageDefaultValue: conf.Format,
    37  			},
    38  		},
    39  		&conf,
    40  		types.GinkgoFlagSections{},
    41  	)
    42  	if err != nil {
    43  		panic(err)
    44  	}
    45  
    46  	return command.Command{
    47  		Name:          "outline",
    48  		Usage:         "ginkgo outline <filename>",
    49  		ShortDoc:      "Create an outline of Ginkgo symbols for a file",
    50  		Documentation: "To read from stdin, use: `ginkgo outline -`",
    51  		DocLink:       "creating-an-outline-of-specs",
    52  		Flags:         flags,
    53  		Command: func(args []string, _ []string) {
    54  			outlineFile(args, conf.Format)
    55  		},
    56  	}
    57  }
    58  
    59  func outlineFile(args []string, format string) {
    60  	if len(args) != 1 {
    61  		command.AbortWithUsage("outline expects exactly one argument")
    62  	}
    63  
    64  	filename := args[0]
    65  	var src *os.File
    66  	if filename == stdinAlias {
    67  		src = os.Stdin
    68  	} else {
    69  		var err error
    70  		src, err = os.Open(filename)
    71  		command.AbortIfError("Failed to open file:", err)
    72  	}
    73  
    74  	fset := token.NewFileSet()
    75  
    76  	parsedSrc, err := parser.ParseFile(fset, filename, src, 0)
    77  	command.AbortIfError("Failed to parse source:", err)
    78  
    79  	o, err := FromASTFile(fset, parsedSrc)
    80  	command.AbortIfError("Failed to create outline:", err)
    81  
    82  	var oerr error
    83  	switch format {
    84  	case "csv":
    85  		_, oerr = fmt.Print(o)
    86  	case "indent":
    87  		_, oerr = fmt.Print(o.StringIndent(indentWidth))
    88  	case "json":
    89  		b, err := json.Marshal(o)
    90  		if err != nil {
    91  			println(fmt.Sprintf("error marshalling to json: %s", err))
    92  		}
    93  		_, oerr = fmt.Println(string(b))
    94  	default:
    95  		command.AbortWith("Format %s not accepted", format)
    96  	}
    97  	command.AbortIfError("Failed to write outline:", oerr)
    98  }