zagane

command module
v0.5.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2020 License: MIT Imports: 5 Imported by: 0

README

zagane

CircleCI GoDoc

zagane is a static analysis tool which can find bugs in spanner's code. zagane consists of several analyzers.

  • unstopiter: it finds iterators which did not stop.
  • unclosetx: it finds transactions which does not close
  • wraperr: it finds (*spanner.Client).ReadWriteTransaction calls which returns wrapped errors

Install

You can get zagane by go get command.

$ go get -u github.com/gcpug/zagane

How to use

zagane run with go vet as below when Go is 1.12 and higher.

$ go vet -vettool=$(which zagane) github.com/gcpug/spshovel/...
# github.com/gcpug/spshovel/spanner
spanner/spanner_service.go:29:29: iterator must be stop

When Go is lower than 1.12, just run zagane command with the package name (import path). But it cannot accept some options such as --tags.

$ zagane github.com/gcpug/spshovel/...
~/go/src/github.com/gcpug/spshovel/spanner/spanner_service.go:29:29: iterator must be stop

Analyzers

unstopiter

unstopiter finds spanner.RowIterator which is not calling Stop method or Do method such as below code.

iter := client.Single().Query(ctx, stmt)
for {
	row, err := iter.Next()
	// ...
}

This code must be fixed as below.

iter := client.Single().Query(ctx, stmt)
defer iter.Stop()
for {
	row, err := iter.Next()
	// ...
}
unclosetx

unclosetx finds spanner.ReadOnlyTransaction which is not calling Close method such as below code.

tx := client.ReadOnlyTransaction()
// ...

This code must be fixed as below.

tx := client.ReadOnlyTransaction()
defer tx.Close()
// ...

When a transaction is created by (*spanner.Client).Single, unclosetx ignore it.

wraperr

wraperr finds ReadWriteTransaction calls which returns wrapped errors such as the below code.

func f(ctx context.Context, client *spanner.Client) {
	client.ReadWriteTransaction(ctx, func(ctx context.Context, txn *spanner.ReadWriteTransaction) error {
		stmt := spanner.Statement{SQL: `SELECT 1`}
		_, err := client.Single().Query(ctx, stmt).Next()
		if err != nil {
			return errors.Wrap(err, "wrapped") // want "must not be wrapped"
		}
		return nil
	})
}

This code must be fixed as below.

func f(ctx context.Context, client *spanner.Client) {
	client.ReadWriteTransaction(ctx, func(ctx context.Context, txn *spanner.ReadWriteTransaction) error {
		stmt := spanner.Statement{SQL: `SELECT 1`}
		_, err := client.Single().Query(ctx, stmt).Next()
		if err != nil {
			return err
		}
		return nil
	})
}

Ignore Checks

Analyzers ignore nodes which are annotated by staticcheck's style comments as belows. A ignore comment includes analyzer names and reason of ignoring checking. If you specify zagane as analyzer name, all analyzers ignore corresponding code.

//lint:ignore zagane reason
var n int

//lint:ignore unstopiter reason
_, _ = client.Single().Query(ctx, stmt).Next()

Analyze with golang.org/x/tools/go/analysis

You can get analyzers of zagane from zagane.Analyzers. And you can use them with unitchecker.

Why name is "zagane"?

"zagane" (座金) means "washer" in Japanese. A washer works between a spanner and other parts. zagane also works between Cloud Spanner and your applications.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
passes

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL