Skip to content

Commit

Permalink
cmd/gorules: initial commit (#229)
Browse files Browse the repository at this point in the history
`gorules` is a helper binary that inspects `gorules` files.
The first command is `gorules doc` that extracts the documentation.
  • Loading branch information
quasilyte authored Apr 29, 2021
1 parent 7a5609f commit 0a861a9
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 0 deletions.
10 changes: 10 additions & 0 deletions cmd/gorules/go.mod
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
)
49 changes: 49 additions & 0 deletions cmd/gorules/go.sum
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=
137 changes: 137 additions & 0 deletions cmd/gorules/main.go
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
}

0 comments on commit 0a861a9

Please sign in to comment.