Documentation ¶
Overview ¶
Package tenet provides a library to write a tenet in Go.
The tenet's API is served as an RPC plugin (github.com/lingo- reviews/dev/plugin) consumed by the lingo executable (github.com/lingo- reviews/lingo). The following is a fully functional tenet plugin (See github.com/lingo-reviews/tenets/go/tenets for more examples):
package main
import (
"go/ast" "github.com/lingo-reviews/tenets/go/dev/plugin" "github.com/lingo-reviews/tenets/go/dev/tenet"
)
type commentTenet struct { tenet.Base }
func main() { c := &commentTenet{} c.SetInfo(tenet.Info{ Name: "simpleseed", Usage: "every comment should be awesome", Language: "golang", }) c.SmellNode(func(file *tenet.File, comment *ast.Comment) error { if comment.Text != "most awesome comment ever" { c.AddNodeIssue(file, comment, 0.9) } return nil }) c.AddComment("this comment could be more awesome") plugin.Serve(c) }
Index ¶
- func APIInfo(i *Info) *api.Info
- func APIIssue(i *Issue) *api.Issue
- func RandString(n int) string
- type Base
- func (b *Base) Errors() chan error
- func (b *Base) Info() *Info
- func (b *Base) Init()
- func (b *Base) MixinConfigOptions(opts []*api.Option) error
- func (b *Base) NewReview() *review
- func (b *Base) RegisterIssue(issueName string, opts ...RegisterIssueOption) string
- func (b *Base) RegisterMetric(key string) func(val interface{}) RaiseIssueOption
- func (b *Base) RegisterOption(name string, value string, usage string) *string
- func (b *Base) RegisterTag(tag string) RaiseIssueOption
- func (b *Base) SendError(err error)
- func (b *Base) SetInfo(i Info) Tenet
- func (b *Base) SmellLine(f smellLineFunc) Tenet
- func (b *Base) SmellNode(f smellNodeFunc) Tenet
- type BaseFile
- type BaseReview
- type BaseTenet
- type CommentContext
- type File
- type Info
- type Issue
- type RaiseIssueOption
- type RegisterIssueOption
- type Review
- type Tenet
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func RandString ¶
Types ¶
type Base ¶
type Base struct {
// contains filtered or unexported fields
}
Base implements the Tenet interface and is intended to be composed with 3rd party tenets.
func (*Base) RegisterIssue ¶
func (b *Base) RegisterIssue(issueName string, opts ...RegisterIssueOption) string
func (*Base) RegisterMetric ¶
func (b *Base) RegisterMetric(key string) func(val interface{}) RaiseIssueOption
RegisterMetric registers a metric key name that can be used when raising an issue.
func (*Base) RegisterOption ¶
TODO(waigani) support interface values
func (*Base) RegisterTag ¶
func (b *Base) RegisterTag(tag string) RaiseIssueOption
RegisterTag registers a tag name that can be used when registering an issue.
type BaseFile ¶
type BaseFile interface {
// contains filtered or unexported methods
}
File represents a file being checked. It is intended for use by the system.
type BaseReview ¶
type BaseReview interface { // Starts the review. This should be called in a goroutine before sending // files to the review. StartReview() // Closes a review Close() // Send files to a review. SendFile(*api.File) // Call this when you've finished sending all the files to review. EndReview() // File currently being reviewed. File() File // A chan of issues found in the review. Issues() chan *Issue // TODO(waigani) move this Tenet interface as it is useful for tenet authors. // A temporary working directory that the review can use. TMPDIR() (dirpath string, err error) // contains filtered or unexported methods }
BaseReview is only for use by the system.
type BaseTenet ¶
type BaseTenet interface { Init() NewReview() *review Info() *Info MixinConfigOptions(opts []*api.Option) error SendError(error) Errors() chan error // contains filtered or unexported methods }
BaseReview is only for use by the system.
type CommentContext ¶
type CommentContext int
CommentContext is a bit operator which dictates when the comment should be used. e.g. first, second, last time an issue is encountered.
const ( DefaultComment CommentContext = 1 << iota FirstComment SecondComment ThirdComment FourthComment FifthComment InFirstFile InSecondFile InThirdFile InFourthFile InFifthFile InEveryFile InOverall )
type File ¶
type File interface { // Returns the source code a line i. Line(i int) []byte // Returns all source code for this file. Lines() [][]byte // Returns the ast.File node of this file. AST() *ast.File // The name of the file currently being reviewed. Filename() string // Returns the FileSet this file is a member of. Fset() *token.FileSet }
File represents the current file being reviewed.
type Info ¶
type Info struct { Name string Usage string Description string Language string SearchTags []string Options []*option Version string // contains filtered or unexported fields }
information about the tenet
type Issue ¶
type Issue struct { Name string // Name is the the name of the checker that added the issue Position *issueRange // position in source file Comment string // The rendered comment for this issue. CommVars map[string]interface{} // key/value pairs for use in comment template variables e.g. {{.somevarname}} CtxBefore string // source lines before the problem line(s) LineText string // the source line(s) CtxAfter string // source lines after the problem line(s) Link string // (optional) the link to the style guide for the problem NewCode bool // When checking a diff, this indicates if the issue was found in existing or new code. Err error // Any err encounted while building the issue. Metrics map[string]interface{} // Any metrics that this issue was raised with Tags []string // Any tags this issue was raised with. // TODO(matt, waigani) Implement this. Possibly use github.com/waigani/diffparser and github.com/waigani/astnode. // The idea is: // - issue.DiffFix() returns a diff patch to fix the issue. // - run Lingo with --fix. If issue.CanFix, Lingo prompts the user to keep/discard the patch. // - Lingo assembles patchs into one diff and, depending on flags, either applies the patch or just saves the diff to file. Patch string // A diff patch resolving the issue. // contains filtered or unexported fields }
Problem represents a problem in some source code. Borrows from problem struct from https://github.com/golang/lint/blob/master/lint.go
type RaiseIssueOption ¶
type RaiseIssueOption func(*Issue)
func CommentVar ¶
func CommentVar(key string, value interface{}) RaiseIssueOption
CommentVar stores key/value pairs used to populate the rule's comment templates e.g. r.AddInfo("spaces", 2) r.Comments = []string{"You have {{.spaces}} after a period, when the styleguide specifies that there should only be one." CommentVar returns an issueOption which sets a variable to be used in the comments.
type RegisterIssueOption ¶
type RegisterIssueOption func(*Issue)
func AddComment ¶
func AddComment(comment string, ctx ...CommentContext) RegisterIssueOption
type Review ¶
type Review interface { // RaiseLineIssue sends the named issue (issueName) to lingo, along with // the start and end lines of the issue and metadata from opts. RaiseLineIssue(issueName string, start, end int, opts ...RaiseIssueOption) Review // RaiseNodeIssue sends the named issue (issueName) to lingo, along with metadata from n and opts. RaiseNodeIssue(issueName string, n ast.Node, opts ...RaiseIssueOption) Review // File is the current file being reviewed. File() File // The current smell will no longer be called at all. SmellDone() // The current smell will no longer be called for the current file. SmellDoneWithFile() // The current file will not be smelt by this tenet again. This should // only be used if it is not logical to keep looking. If you just want to // limit the number of times an issue is raised, use comment contexts. e.g. // tenet.FirstFile FileDone() }
Review should only be used inside SmellNode and SmellLine.
type Tenet ¶
type Tenet interface { // Returns information on the tenet. Info() *Info // Sets information about the tenet used by the lingo client. SetInfo(Info) Tenet // Register a metric which can be added to a raised issue. RegisterMetric(key string) func(interface{}) RaiseIssueOption // Register a tag which can be added to a raised issue RegisterTag(tag string) RaiseIssueOption // Registers an issue that this tenet can raise. The string returned is // the the name of the issue which is used as the first argument to // Review.RaiseNodeIssue or Review.RaiseLineIssue RegisterIssue(issueName string, opts ...RegisterIssueOption) string // Returns the value of the option. RegisterOption(name, value, usage string) *string // SmellNode will smell every node that matches the type in smellNodeFunc. SmellNode(f smellNodeFunc) Tenet // SmellLine will smell every line of every file. SmellLine(f smellLineFunc) Tenet }
Tenet defines what the tenet is about and sets anything needed before a review. Tenet should never be called inside SmellNode and SmellLine.