github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/cli/sqlfmt.go (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package cli
    12  
    13  import (
    14  	"fmt"
    15  	"io/ioutil"
    16  	"os"
    17  
    18  	"github.com/cockroachdb/cockroach/pkg/sql/parser"
    19  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    20  	"github.com/cockroachdb/errors"
    21  	"github.com/spf13/cobra"
    22  )
    23  
    24  // TODO(mjibson): This subcommand has more flags than I would prefer. My
    25  // goal is to have it have just -e and nothing else. gofmt initially started
    26  // with tabs/spaces and width specifiers but later regretted that decision
    27  // and removed them. I would like to get to the point where we achieve SQL
    28  // formatting nirvana and we make this an opinionated formatter with few or
    29  // zero options, hopefully before 2.1.
    30  
    31  var sqlfmtCmd = &cobra.Command{
    32  	Use:   "sqlfmt",
    33  	Short: "format SQL statements",
    34  	Long:  "Formats SQL statements from stdin to line length n.",
    35  	RunE:  runSQLFmt,
    36  }
    37  
    38  func runSQLFmt(cmd *cobra.Command, args []string) error {
    39  	if sqlfmtCtx.len < 1 {
    40  		return errors.Errorf("line length must be > 0: %d", sqlfmtCtx.len)
    41  	}
    42  	if sqlfmtCtx.tabWidth < 1 {
    43  		return errors.Errorf("tab width must be > 0: %d", sqlfmtCtx.tabWidth)
    44  	}
    45  
    46  	var sl parser.Statements
    47  	if len(sqlfmtCtx.execStmts) != 0 {
    48  		for _, exec := range sqlfmtCtx.execStmts {
    49  			stmts, err := parser.Parse(exec)
    50  			if err != nil {
    51  				return err
    52  			}
    53  			sl = append(sl, stmts...)
    54  		}
    55  	} else {
    56  		in, err := ioutil.ReadAll(os.Stdin)
    57  		if err != nil {
    58  			return err
    59  		}
    60  		sl, err = parser.Parse(string(in))
    61  		if err != nil {
    62  			return err
    63  		}
    64  	}
    65  
    66  	cfg := tree.DefaultPrettyCfg()
    67  	cfg.UseTabs = !sqlfmtCtx.useSpaces
    68  	cfg.LineWidth = sqlfmtCtx.len
    69  	cfg.TabWidth = sqlfmtCtx.tabWidth
    70  	cfg.Simplify = !sqlfmtCtx.noSimplify
    71  	cfg.Align = tree.PrettyNoAlign
    72  	cfg.JSONFmt = true
    73  	if sqlfmtCtx.align {
    74  		cfg.Align = tree.PrettyAlignAndDeindent
    75  	}
    76  
    77  	for i := range sl {
    78  		fmt.Print(cfg.Pretty(sl[i].AST))
    79  		if len(sl) > 1 {
    80  			fmt.Print(";")
    81  		}
    82  		fmt.Println()
    83  	}
    84  	return nil
    85  }