-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
`gorules` is a helper binary that inspects `gorules` files. The first command is `gorules doc` that extracts the documentation.
- Loading branch information
Showing
3 changed files
with
196 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
module github.com/quasilyte/go-ruleguard/cmd/gorules | ||
|
||
go 1.16 | ||
|
||
require ( | ||
github.com/cespare/subcmd v1.1.0 | ||
github.com/go-toolsmith/strparse v1.0.0 // indirect | ||
github.com/quasilyte/go-ruleguard v0.3.5-0.20210428232022-7a5609fc5ec6 | ||
github.com/quasilyte/go-ruleguard/rules v0.0.0-20210428232022-7a5609fc5ec6 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
github.com/cespare/subcmd v1.1.0 h1:r60BAqAKOGcBjxHmV9/WYvq5Qbp3xW9ByB+fRjtty9U= | ||
github.com/cespare/subcmd v1.1.0/go.mod h1:wnVjukiuhSlhZSgGHUilbkHykG7Oglb0sJXpUQ+MoUw= | ||
github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ= | ||
github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= | ||
github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= | ||
github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= | ||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||
github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30= | ||
github.com/quasilyte/go-ruleguard v0.3.4 h1:F6l5p6+7WBcTKS7foNQ4wqA39zjn2+RbdbyzGxIq1B0= | ||
github.com/quasilyte/go-ruleguard v0.3.4/go.mod h1:57FZgMnoo6jqxkYKmVj5Fc8vOt0rVzoE/UNAmFFIPqA= | ||
github.com/quasilyte/go-ruleguard v0.3.5-0.20210428232022-7a5609fc5ec6 h1:cHaMS4GXRhIH499NgnDipyy17VgiVuk2D6N+calwncU= | ||
github.com/quasilyte/go-ruleguard v0.3.5-0.20210428232022-7a5609fc5ec6/go.mod h1:B+eagO+T9AoTZFYuROGERvVCM6K2RXDVBsviDUjI4zs= | ||
github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= | ||
github.com/quasilyte/go-ruleguard/dsl v0.3.2 h1:ULi3SLXvDUgb0u2IM5xU6er9KeWBSaUh1NlDjCgLHU8= | ||
github.com/quasilyte/go-ruleguard/dsl v0.3.2/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= | ||
github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc= | ||
github.com/quasilyte/go-ruleguard/rules v0.0.0-20210203162857-b223e0831f88/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= | ||
github.com/quasilyte/go-ruleguard/rules v0.0.0-20210428214800-545e0d2e0bf7/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= | ||
github.com/quasilyte/go-ruleguard/rules v0.0.0-20210428232022-7a5609fc5ec6 h1:hxEUKRHzSPA0VzHFcQ5EevDk9mNJojv0zg/5rY2wZ4E= | ||
github.com/quasilyte/go-ruleguard/rules v0.0.0-20210428232022-7a5609fc5ec6/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= | ||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= | ||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= | ||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||
golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= | ||
golang.org/x/tools v0.0.0-20201230224404-63754364767c h1:xx3+TTG3yS1I6Ola5Kapxr5vZu85vKkcwKyV6ke9fHA= | ||
golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= | ||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"flag" | ||
"fmt" | ||
"go/token" | ||
"io/ioutil" | ||
"log" | ||
"path/filepath" | ||
"strings" | ||
|
||
"github.com/cespare/subcmd" | ||
"github.com/quasilyte/go-ruleguard/ruleguard" | ||
) | ||
|
||
func main() { | ||
cmds := []subcmd.Command{ | ||
{ | ||
Name: "doc", | ||
Description: "query rules documentation", | ||
Do: docMain, | ||
}, | ||
} | ||
|
||
subcmd.Run(cmds) | ||
} | ||
|
||
func docMain(args []string) { | ||
if err := docCommand(args); err != nil { | ||
log.Fatal(err) | ||
} | ||
} | ||
|
||
func docCommand(args []string) error { | ||
type JsonListEntry struct { | ||
Name string | ||
Filename string | ||
Line int | ||
DocSummary string | ||
DocBefore string | ||
DocAfter string | ||
DocTags []string | ||
} | ||
type JsonList struct { | ||
List []JsonListEntry | ||
} | ||
|
||
fs := flag.NewFlagSet("gorules doc", flag.ExitOnError) | ||
flagRules := fs.String("rules", "", `comma-separated list of ruleguard file paths`) | ||
flagJson := fs.Bool("json", false, `format the output as JSON`) | ||
fs.Parse(args) | ||
|
||
var groupName string | ||
extraArgs := fs.Args() | ||
if len(extraArgs) != 0 { | ||
groupName = extraArgs[0] | ||
} | ||
|
||
e := ruleguard.NewEngine() | ||
fset := token.NewFileSet() | ||
ctx := &ruleguard.ParseContext{ | ||
Fset: fset, | ||
} | ||
filenames := strings.Split(*flagRules, ",") | ||
for _, filename := range filenames { | ||
filename = strings.TrimSpace(filename) | ||
data, err := ioutil.ReadFile(filename) | ||
if err != nil { | ||
return fmt.Errorf("read rules file: %v", err) | ||
} | ||
if err := e.Load(ctx, filename, bytes.NewReader(data)); err != nil { | ||
return fmt.Errorf("parse rules file: %v", err) | ||
} | ||
} | ||
|
||
if *flagJson { | ||
var result JsonList | ||
for _, g := range e.LoadedGroups() { | ||
result.List = append(result.List, JsonListEntry{ | ||
Name: g.Name, | ||
Line: g.Line, | ||
Filename: g.Filename, | ||
DocSummary: g.DocSummary, | ||
DocBefore: g.DocBefore, | ||
DocAfter: g.DocAfter, | ||
DocTags: g.DocTags, | ||
}) | ||
} | ||
var buf bytes.Buffer | ||
enc := json.NewEncoder(&buf) | ||
enc.SetEscapeHTML(false) | ||
if err := enc.Encode(result); err != nil { | ||
return err | ||
} | ||
var pretty bytes.Buffer | ||
if err := json.Indent(&pretty, buf.Bytes(), "", " "); err != nil { | ||
return err | ||
} | ||
fmt.Print(pretty.String()) | ||
return nil | ||
} | ||
if groupName != "" { | ||
var g *ruleguard.GoRuleGroup | ||
groups := e.LoadedGroups() | ||
for i := range groups { | ||
if groups[i].Name == groupName { | ||
g = &groups[i] | ||
break | ||
} | ||
} | ||
if g == nil { | ||
return fmt.Errorf("the requested %s group was not loaded", groupName) | ||
} | ||
fmt.Printf("%s:%d: %s\n\n", filepath.Base(g.Filename), g.Line, g.Name) | ||
fmt.Printf("Full path: %s\n\n", g.Filename) | ||
if g.DocSummary != "" { | ||
fmt.Printf("Summary: %s\n\n", g.DocSummary) | ||
} | ||
if len(g.DocTags) != 0 { | ||
fmt.Printf("Tags: %v\n\n", g.DocTags) | ||
} | ||
if g.DocBefore != "" && g.DocAfter != "" { | ||
fmt.Printf("Before:\n") | ||
fmt.Printf("\t%s\n", g.DocBefore) | ||
fmt.Printf("After:\n") | ||
fmt.Printf("\t%s\n", g.DocAfter) | ||
} | ||
} else { | ||
for _, g := range e.LoadedGroups() { | ||
fmt.Printf("%s:%d: %s\n", filepath.Base(g.Filename), g.Line, g.Name) | ||
} | ||
} | ||
|
||
return nil | ||
} |