Skip to content

Commit 1e7caf2

Browse files
committed
refactor: use parseCmd global instead of NewCmdParse function
Match the style of other commands in cmd.go by using a global variable and registering flags in init(). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 4fe64c4 commit 1e7caf2

File tree

2 files changed

+68
-73
lines changed

2 files changed

+68
-73
lines changed

internal/cmd/cmd.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ func init() {
3030
initCmd.Flags().BoolP("v1", "", false, "generate v1 config yaml file")
3131
initCmd.Flags().BoolP("v2", "", true, "generate v2 config yaml file")
3232
initCmd.MarkFlagsMutuallyExclusive("v1", "v2")
33+
parseCmd.Flags().StringP("dialect", "d", "", "SQL dialect to use (postgresql, mysql, or sqlite)")
3334
}
3435

3536
// Do runs the command logic.
@@ -44,7 +45,7 @@ func Do(args []string, stdin io.Reader, stdout io.Writer, stderr io.Writer) int
4445
rootCmd.AddCommand(diffCmd)
4546
rootCmd.AddCommand(genCmd)
4647
rootCmd.AddCommand(initCmd)
47-
rootCmd.AddCommand(NewCmdParse())
48+
rootCmd.AddCommand(parseCmd)
4849
rootCmd.AddCommand(versionCmd)
4950
rootCmd.AddCommand(verifyCmd)
5051
rootCmd.AddCommand(pushCmd)

internal/cmd/parse.go

Lines changed: 66 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@ import (
1414
"github.com/sqlc-dev/sqlc/internal/sql/ast"
1515
)
1616

17-
func NewCmdParse() *cobra.Command {
18-
cmd := &cobra.Command{
19-
Use: "parse [file]",
20-
Short: "Parse SQL and output the AST as JSON (experimental)",
21-
Long: `Parse SQL from a file or stdin and output the abstract syntax tree as JSON.
17+
var parseCmd = &cobra.Command{
18+
Use: "parse [file]",
19+
Short: "Parse SQL and output the AST as JSON (experimental)",
20+
Long: `Parse SQL from a file or stdin and output the abstract syntax tree as JSON.
2221
2322
This command is experimental and requires the 'parsecmd' experiment to be enabled.
2423
Enable it by setting: SQLCEXPERIMENT=parsecmd
@@ -32,77 +31,72 @@ Examples:
3231
3332
# Parse SQLite SQL
3433
SQLCEXPERIMENT=parsecmd sqlc parse --dialect sqlite queries.sql`,
35-
Args: cobra.MaximumNArgs(1),
36-
RunE: func(cmd *cobra.Command, args []string) error {
37-
env := ParseEnv(cmd)
38-
if !env.Experiment.ParseCmd {
39-
return fmt.Errorf("parse command requires the 'parsecmd' experiment to be enabled.\nSet SQLCEXPERIMENT=parsecmd to use this command")
40-
}
41-
42-
dialect, err := cmd.Flags().GetString("dialect")
34+
Args: cobra.MaximumNArgs(1),
35+
RunE: func(cmd *cobra.Command, args []string) error {
36+
env := ParseEnv(cmd)
37+
if !env.Experiment.ParseCmd {
38+
return fmt.Errorf("parse command requires the 'parsecmd' experiment to be enabled.\nSet SQLCEXPERIMENT=parsecmd to use this command")
39+
}
40+
41+
dialect, err := cmd.Flags().GetString("dialect")
42+
if err != nil {
43+
return err
44+
}
45+
if dialect == "" {
46+
return fmt.Errorf("--dialect flag is required (postgresql, mysql, or sqlite)")
47+
}
48+
49+
// Determine input source
50+
var input io.Reader
51+
if len(args) == 1 {
52+
file, err := os.Open(args[0])
4353
if err != nil {
44-
return err
45-
}
46-
if dialect == "" {
47-
return fmt.Errorf("--dialect flag is required (postgresql, mysql, or sqlite)")
48-
}
49-
50-
// Determine input source
51-
var input io.Reader
52-
if len(args) == 1 {
53-
file, err := os.Open(args[0])
54-
if err != nil {
55-
return fmt.Errorf("failed to open file: %w", err)
56-
}
57-
defer file.Close()
58-
input = file
59-
} else {
60-
// Check if stdin has data
61-
stat, err := os.Stdin.Stat()
62-
if err != nil {
63-
return fmt.Errorf("failed to stat stdin: %w", err)
64-
}
65-
if (stat.Mode() & os.ModeCharDevice) != 0 {
66-
return fmt.Errorf("no input provided. Specify a file path or pipe SQL via stdin")
67-
}
68-
input = cmd.InOrStdin()
69-
}
70-
71-
// Parse SQL based on dialect
72-
var stmts []ast.Statement
73-
switch dialect {
74-
case "postgresql", "postgres", "pg":
75-
parser := postgresql.NewParser()
76-
stmts, err = parser.Parse(input)
77-
case "mysql":
78-
parser := dolphin.NewParser()
79-
stmts, err = parser.Parse(input)
80-
case "sqlite":
81-
parser := sqlite.NewParser()
82-
stmts, err = parser.Parse(input)
83-
default:
84-
return fmt.Errorf("unsupported dialect: %s (use postgresql, mysql, or sqlite)", dialect)
54+
return fmt.Errorf("failed to open file: %w", err)
8555
}
56+
defer file.Close()
57+
input = file
58+
} else {
59+
// Check if stdin has data
60+
stat, err := os.Stdin.Stat()
8661
if err != nil {
87-
return fmt.Errorf("parse error: %w", err)
62+
return fmt.Errorf("failed to stat stdin: %w", err)
8863
}
89-
90-
// Output AST as JSON
91-
stdout := cmd.OutOrStdout()
92-
encoder := json.NewEncoder(stdout)
93-
encoder.SetIndent("", " ")
94-
95-
for _, stmt := range stmts {
96-
if err := encoder.Encode(stmt.Raw); err != nil {
97-
return fmt.Errorf("failed to encode AST: %w", err)
98-
}
64+
if (stat.Mode() & os.ModeCharDevice) != 0 {
65+
return fmt.Errorf("no input provided. Specify a file path or pipe SQL via stdin")
9966
}
67+
input = cmd.InOrStdin()
68+
}
69+
70+
// Parse SQL based on dialect
71+
var stmts []ast.Statement
72+
switch dialect {
73+
case "postgresql", "postgres", "pg":
74+
parser := postgresql.NewParser()
75+
stmts, err = parser.Parse(input)
76+
case "mysql":
77+
parser := dolphin.NewParser()
78+
stmts, err = parser.Parse(input)
79+
case "sqlite":
80+
parser := sqlite.NewParser()
81+
stmts, err = parser.Parse(input)
82+
default:
83+
return fmt.Errorf("unsupported dialect: %s (use postgresql, mysql, or sqlite)", dialect)
84+
}
85+
if err != nil {
86+
return fmt.Errorf("parse error: %w", err)
87+
}
88+
89+
// Output AST as JSON
90+
stdout := cmd.OutOrStdout()
91+
encoder := json.NewEncoder(stdout)
92+
encoder.SetIndent("", " ")
93+
94+
for _, stmt := range stmts {
95+
if err := encoder.Encode(stmt.Raw); err != nil {
96+
return fmt.Errorf("failed to encode AST: %w", err)
97+
}
98+
}
10099

101-
return nil
102-
},
103-
}
104-
105-
cmd.Flags().StringP("dialect", "d", "", "SQL dialect to use (postgresql, mysql, or sqlite)")
106-
107-
return cmd
100+
return nil
101+
},
108102
}

0 commit comments

Comments
 (0)