Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidGamba committed Jun 8, 2024
1 parent fef300a commit 1f1656d
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 5 deletions.
137 changes: 134 additions & 3 deletions bake/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ func GetFuncDeclForPackage(dir string, m *map[string]FuncDecl) error {
return nil
}

// The goal is to be able to find the getoptions.CommandFn calls.
// Also, we need to inspect the function and get the opt.<Type> calls to know what options are being used.
//
// func Asciidoc(opt *getoptions.GetOpt) getoptions.CommandFn {
// opt.String("lang", "en", opt.ValidValues("en", "es"))
// opt.String("hello", "world")
// opt.String("hola", "mundo")
// return func(ctx context.Context, opt *getoptions.GetOpt, args []string) error {
func PrintAst(dir string) error {
cfg := &packages.Config{Mode: packages.NeedFiles | packages.NeedSyntax, Dir: dir}
pkgs, err := packages.Load(cfg, ".")
Expand Down Expand Up @@ -89,8 +97,131 @@ func PrintAst(dir string) error {
description := x.Doc.Text()
var buf bytes.Buffer
printer.Fprint(&buf, fset, x.Type)
Logger.Printf("file: %s, name: %s, desc: %s\n", file, name, strings.TrimSpace(description))
Logger.Printf("file: %s, name: %s, type: %s\n", file, name, buf.String())
Logger.Printf("file: %s, FuncDecl name: %s, desc: %s\n", file, name, strings.TrimSpace(description))
Logger.Printf("file: %s, FuncDecl name: %s, type: %s\n", file, name, buf.String())

// Check for Expressions of opt type
ast.Inspect(n, func(n ast.Node) bool {
switch x := n.(type) {
case *ast.BlockStmt:
for i, stmt := range x.List {
Logger.Printf("i: %d\n", i)
Logger.Printf("stmt: %T\n", stmt)
// We are expecting the expression before the return function
_, ok := stmt.(*ast.ReturnStmt)
if ok {
return false
}
Logger.Printf("inspect stmt: %T\n", stmt)
exprStmt, ok := stmt.(*ast.ExprStmt)
if !ok {
continue
}
// spew.Dump(exprStmt)

// Check for CallExpr
ast.Inspect(exprStmt, func(n ast.Node) bool {
switch x := n.(type) {
case *ast.CallExpr:
fun, ok := x.Fun.(*ast.SelectorExpr)
if !ok {
return false
}
xIdent, ok := fun.X.(*ast.Ident)
if !ok {
return false
}
xSel := fun.Sel.Name
Logger.Printf("X: %s, Selector: %s\n", xIdent.Name, xSel)

// Check for args
for _, arg := range x.Args {
Logger.Printf("arg: %T\n", arg)
spew.Dump(arg)
}
return false
}
return true
})
}
}
return true
})
}
}
return true
})
}
}
return nil
}

// The goal is to be able to find the getoptions.CommandFn calls.
// Also, we need to inspect the function and get the opt.<Type> calls to know what options are being used.
//
// func Asciidoc(opt *getoptions.GetOpt) getoptions.CommandFn {
// opt.String("lang", "en", opt.ValidValues("en", "es"))
// opt.String("hello", "world")
// opt.String("hola", "mundo")
// return func(ctx context.Context, opt *getoptions.GetOpt, args []string) error {
func ListAst(dir string) error {
cfg := &packages.Config{Mode: packages.NeedFiles | packages.NeedSyntax, Dir: dir}
pkgs, err := packages.Load(cfg, ".")
if err != nil {
return fmt.Errorf("failed to load packages: %w", err)
}
for _, pkg := range pkgs {
// Logger.Println(pkg.ID, pkg.GoFiles)
for _, file := range pkg.GoFiles {
// Logger.Printf("file: %s\n", file)
// parse file
fset := token.NewFileSet()
fset.AddFile(file, fset.Base(), len(file))
f, err := parser.ParseFile(fset, file, nil, parser.ParseComments)
if err != nil {
return fmt.Errorf("failed to parse file: %w", err)
}
// Iterate through every node in the file
ast.Inspect(f, func(n ast.Node) bool {
switch x := n.(type) {
// Check function declarations for exported functions
case *ast.FuncDecl:
if x.Name.IsExported() {
name := x.Name.Name
description := x.Doc.Text()
var buf bytes.Buffer
printer.Fprint(&buf, fset, x.Type)
Logger.Printf("file: %s\n", file)
Logger.Printf("type: %s, name: %s, desc: %s\n", buf.String(), name, strings.TrimSpace(description))

// Check Params
// Expect opt *getoptions.GetOpt
if len(x.Type.Params.List) != 1 {
return false
}
for _, param := range x.Type.Params.List {
name := param.Names[0].Name
var buf bytes.Buffer
printer.Fprint(&buf, fset, param.Type)
Logger.Printf("name: %s, %s\n", name, buf.String())
if buf.String() != "*getoptions.GetOpt" {
return false
}
}

// Check Results
// Expect getoptions.CommandFn
if len(x.Type.Results.List) != 1 {
return false
}
for _, result := range x.Type.Results.List {
var buf bytes.Buffer
printer.Fprint(&buf, fset, result.Type)
Logger.Printf("result: %s\n", buf.String())
if buf.String() != "getoptions.CommandFn" {
return false
}
}

// Check for Expressions of opt type
ast.Inspect(n, func(n ast.Node) bool {
Expand Down Expand Up @@ -124,7 +255,7 @@ func PrintAst(dir string) error {
return false
}
xSel := fun.Sel.Name
Logger.Printf("X: %s %s\n", xIdent.Name, xSel)
Logger.Printf("X: %s, Selector: %s\n", xIdent.Name, xSel)

// Check for args
for _, arg := range x.Args {
Expand Down
6 changes: 5 additions & 1 deletion bake/examples/website/bake/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ var Logger = log.New(os.Stderr, "", log.LstdFlags)

var TM *dag.TaskMap

func Nothing(s string) error {
return nil
}

// build - Build tasks
func Build(opt *getoptions.GetOpt) getoptions.CommandFn {
// Empty task used to group tasks.
Expand Down Expand Up @@ -96,7 +100,7 @@ func Build(opt *getoptions.GetOpt) getoptions.CommandFn {
// build:index - Builds index page
// NOTE: Run clean before changing the language since no changes will be detected.
func Asciidoc(opt *getoptions.GetOpt) getoptions.CommandFn {
opt.String("lang", "en", opt.ValidValues("en", "es"))
opt.String("lang", "en", opt.ValidValues("en", "es"), opt.Description("Language"))
opt.String("hello", "world")
opt.String("hola", "mundo")
return func(ctx context.Context, opt *getoptions.GetOpt, args []string) error {
Expand Down
17 changes: 16 additions & 1 deletion bake/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,12 @@ func program(args []string) int {
bld := b.NewCommand("list-descriptions", "lists descriptions")
bld.SetCommandFn(ListDescriptionsRun(bakefile))

bast := b.NewCommand("show-ast", "show ast")
bast := b.NewCommand("show-ast", "show raw-ish ast")
bast.SetCommandFn(ShowASTRun(bakefile))

bastList := b.NewCommand("list-ast", "list parsed ast")
bastList.SetCommandFn(ListASTRun(bakefile))

opt.HelpCommand("help", opt.Alias("?"))
remaining, err := opt.Parse(args[1:])
if err != nil {
Expand Down Expand Up @@ -181,3 +184,15 @@ func ShowASTRun(bakefile string) getoptions.CommandFn {
return nil
}
}

func ListASTRun(bakefile string) getoptions.CommandFn {
return func(ctx context.Context, opt *getoptions.GetOpt, args []string) error {
Logger.Printf("bakefile: %s\n", bakefile)
dir := filepath.Dir(bakefile)
err := ListAst(dir)
if err != nil {
return fmt.Errorf("failed to inspect package: %w", err)
}
return nil
}
}

0 comments on commit 1f1656d

Please sign in to comment.