-
Notifications
You must be signed in to change notification settings - Fork 126
/
ast.go
93 lines (77 loc) · 2.42 KB
/
ast.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package cmd
import (
"bytes"
"encoding/json"
"fmt"
"net/url"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"google.golang.org/protobuf/encoding/protojson"
"github.com/Permify/permify/internal/schema"
"github.com/Permify/permify/pkg/cmd/flags"
"github.com/Permify/permify/pkg/development/file"
)
// NewGenerateASTCommand creates a new cobra.Command to generate the Abstract Syntax Tree (AST) from a given file.
// The command expects exactly one argument, which is the URL or path to the file.
// It also allows for flags registration for further validation (like coverage flags).
func NewGenerateASTCommand() *cobra.Command {
command := &cobra.Command{
Use: "ast <file>",
Short: "Generates the AST from a specified file and prints it as JSON.",
RunE: runGenerateAST(),
Args: cobra.ExactArgs(1),
}
f := command.Flags()
f.Bool("pretty", false, "If set to true, produces a human-readable output of the AST.")
command.PreRun = func(cmd *cobra.Command, args []string) {
flags.RegisterAstFlags(f)
}
return command
}
// runGenerateAST creates a closure that generates the AST and returns its JSON representation.
// Depending on the "pretty" flag, the output can be either pretty-printed or raw.
func runGenerateAST() func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
// Fetch the value of the "pretty" flag.
pretty := viper.GetBool("pretty")
// Parse the provided URL.
u, err := url.Parse(args[0])
if err != nil {
return err
}
// Initialize a decoder for the provided URL.
decoder, err := file.NewDecoderFromURL(u)
if err != nil {
return err
}
// Initialize an empty shape to store the decoded schema.
s := &file.Shape{}
// Decode the content from the URL into the shape.
err = decoder.Decode(s)
if err != nil {
return err
}
// Convert the string definitions in the shape to a structured schema.
def, err := schema.NewSchemaFromStringDefinitions(true, s.Schema)
if err != nil {
return err
}
// Serialize the schema definition into JSON.
jsonData, err := protojson.Marshal(def)
if err != nil {
return err
}
// Print the JSON, either prettified or raw based on the "pretty" flag.
if pretty {
var prettyJSON bytes.Buffer
err = json.Indent(&prettyJSON, jsonData, "", " ")
if err != nil {
return err
}
fmt.Println(prettyJSON.String())
} else {
fmt.Println(string(jsonData))
}
return nil
}
}