Skip to content

Commit

Permalink
Rename to spancheck (again)
Browse files Browse the repository at this point in the history
- and implement flags
  • Loading branch information
jjti committed Dec 28, 2023
1 parent 676d662 commit fd857b5
Show file tree
Hide file tree
Showing 15 changed files with 118 additions and 103 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- uses: actions/setup-go@v4
with:
go-version: ${{ env.GO_VERSION }}
- run: cd /tmp && go install github.com/jjti/go-spanlint/cmd/spanlint@${{ env.version }} && spanlint -h
- run: cd /tmp && go install github.com/jjti/go-spancheck/cmd/spancheck@${{ env.version }} && spancheck -h
env:
version: ${{ env.GITHUB_EVENT_PULL_REQUEST_HEAD_SHA || env.GITHUB_REF_SLUG }}

Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ testvendor:
@cp -r testdata/base/vendor testdata/base/src
@cp -r testdata/base/vendor testdata/disableerrorchecks/src
@cp -r testdata/base/vendor testdata/enableall/src
@cp -r testdata/base/vendor testdata/enablechecks/src
@rm -rf testdata/base/vendor

.PHONY: install
install:
go install ./cmd/spanlint
@echo "Installed in $(shell which spanlint)"
go install ./cmd/spancheck
@echo "Installed in $(shell which spancheck)"
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
# go-spanlint
# go-spancheck

![Latest release](https://img.shields.io/github/v/release/jjti/go-spanlint)
[![build](https://github.com/jjti/go-spanlint/actions/workflows/build.yaml/badge.svg)](https://github.com/jjti/go-spanlint/actions/workflows/build.yaml)
[![Go Report Card](https://goreportcard.com/badge/github.com/jjti/go-spanlint)](https://goreportcard.com/report/github.com/jjti/go-spanlint)
![Latest release](https://img.shields.io/github/v/release/jjti/go-spancheck)
[![build](https://github.com/jjti/go-spancheck/actions/workflows/build.yaml/badge.svg)](https://github.com/jjti/go-spancheck/actions/workflows/build.yaml)
[![Go Report Card](https://goreportcard.com/badge/github.com/jjti/go-spancheck)](https://goreportcard.com/report/github.com/jjti/go-spancheck)
[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)

Checks usage of [OpenTelemetry spans](https://opentelemetry.io/docs/instrumentation/go/manual/) from [go.opentelemetry.io/otel/trace](go.opentelemetry.io/otel/trace).

## Installation & Usage

```bash
go install github.com/jjti/go-spanlint/cmd/spanlint@latest
spanlint ./...
go install github.com/jjti/go-spancheck/cmd/spancheck@latest
spancheck ./...
```

## Configuration

Only the `span.End()` check is enabled by default. The others can be enabled with `-enable-all`, `-enable-record-error-check`, or `-enable-set-status-check`.

```txt
$ spanlint -h
Usage of spanlint:
$ spancheck -h
Usage of spancheck:
-disable-end-check
disable the check for calling span.End() after span creation
-enable-all
Expand Down Expand Up @@ -62,7 +62,7 @@ func recordErr(span trace.Span, err error) error {
Using the `-ignore-set-status-check-signatures` flag, the error above can be suppressed:
```bash
spanlint -enable-set-status-check -ignore-set-status-check-signatures 'recordErr' ./...
spancheck -enable-set-status-check -ignore-set-status-check-signatures 'recordErr' ./...
```
## Background
Expand Down
11 changes: 11 additions & 0 deletions cmd/spancheck/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package main

import (
"golang.org/x/tools/go/analysis/singlechecker"

"github.com/jjti/go-spancheck"
)

func main() {
singlechecker.Main(spancheck.NewAnalyzer())
}
65 changes: 0 additions & 65 deletions cmd/spanlint/main.go

This file was deleted.

68 changes: 62 additions & 6 deletions config.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
package spanlint
package spancheck

import "regexp"
import (
"flag"
"fmt"
"log"
"regexp"
"strings"
)

// Config is a configuration for the spanlint analyzer.
var (
ignoreSetStatusCheckSignatures = "ignore-set-status-check-signatures"
ignoreRecordErrorCheckSignatures = "ignore-record-error-check-signatures"
)

// Config is a configuration for the spancheck analyzer.
type Config struct {
fs flag.FlagSet

// EnableAll enables all checks and takes precedence over other fields like
// DisableEndCheck. Ignore*CheckSignatures still apply.
EnableAll bool
Expand All @@ -27,14 +40,57 @@ type Config struct {
IgnoreRecordErrorCheckSignatures *regexp.Regexp
}

// NewDefaultConfig returns a new Config with default values.
func NewDefaultConfig() *Config {
return &Config{
// NewConfig returns a new Config with default values and flags for cli usage.
func NewConfig() *Config {
cfg := &Config{
fs: flag.FlagSet{},
DisableEndCheck: false,
EnableAll: false,
EnableSetStatusCheck: false,
IgnoreSetStatusCheckSignatures: nil,
EnableRecordErrorCheck: false,
IgnoreRecordErrorCheckSignatures: nil,
}

cfg.fs.BoolVar(&cfg.DisableEndCheck, "disable-end-check", cfg.DisableEndCheck, "disable the check for calling span.End() after span creation")
cfg.fs.BoolVar(&cfg.EnableAll, "enable-all", cfg.EnableAll, "enable all checks, overriding individual check flags")
cfg.fs.BoolVar(&cfg.EnableSetStatusCheck, "enable-set-status-check", cfg.EnableSetStatusCheck, "enable check for a span.SetStatus(codes.Error, msg) call when returning an error")
ignoreSetStatusCheckSignatures := flag.String(ignoreSetStatusCheckSignatures, "", "comma-separated list of regex for function signature that disable the span.SetStatus(codes.Error, msg) check on errors")
flag.BoolVar(&cfg.EnableRecordErrorCheck, "enable-record-error-check", cfg.EnableRecordErrorCheck, "enable check for a span.RecordError(err) call when returning an error")
ignoreRecordErrorCheckSignatures := flag.String(ignoreRecordErrorCheckSignatures, "", "comma-separated list of regex for function signature that disable the span.RecordError(err) check on errors")
// Set and parse the flags.

// Parse the signatures.
cfg.IgnoreSetStatusCheckSignatures = parseSignatures(ignoreSetStatusCheckSignatures)
cfg.IgnoreRecordErrorCheckSignatures = parseSignatures(ignoreRecordErrorCheckSignatures)

return cfg
}

func parseSignatures(sigFlag *string) *regexp.Regexp {
if sigFlag == nil || *sigFlag == "" {
return nil
}

sigs := []string{}
for _, sig := range strings.Split(*sigFlag, ",") {
sig = strings.TrimSpace(sig)
if sig == "" {
log.Fatalf("empty disable-error-checks-signature value: %q", sig)
}

sigs = append(sigs, sig)
}

if len(sigs) == 0 {
return nil
}

regex := fmt.Sprintf("(%s)", strings.Join(sigs, "|"))
regexCompiled, err := regexp.Compile(regex)
if err != nil {
log.Fatalf("failed to compile signatures: %v", err)
}

return regexCompiled
}
8 changes: 4 additions & 4 deletions doc.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Package spanlint defines a linter that checks for mistakes with OTEL trace spans.
// Package spancheck defines a linter that checks for mistakes with OTEL trace spans.
//
// # Analyzer spanlint
// # Analyzer spancheck
//
// spanlint: check for mistakes with OpenTelemetry trace spans.
// spancheck: check for mistakes with OpenTelemetry trace spans.
//
// Common mistakes with OTEL trace spans include forgetting to call End:
//
Expand Down Expand Up @@ -34,4 +34,4 @@
// // span.RecordError(err) should be here
// return fmt.Errorf("failed to run task: %w", err)
// }
package spanlint
package spancheck
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/jjti/go-spanlint
module github.com/jjti/go-spancheck

go 1.21.3

Expand Down
22 changes: 17 additions & 5 deletions spanlint.go → spancheck.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package spanlint
package spancheck

import (
_ "embed"
Expand Down Expand Up @@ -28,11 +28,23 @@ var (
)

// NewAnalyzer returns a new analyzer that checks for mistakes with OTEL trace spans.
func NewAnalyzer(config *Config) *analysis.Analyzer {
// Its config is sourced from flags.
func NewAnalyzer() *analysis.Analyzer {
return newAnalyzer(NewConfig())
}

// NewAnalyzerWithConfig returns a new analyzer configured with the Config passed in.
// Its config can be set for testing.
func NewAnalyzerWithConfig(config *Config) *analysis.Analyzer {
return newAnalyzer(config)
}

func newAnalyzer(config *Config) *analysis.Analyzer {
return &analysis.Analyzer{
Name: "spanlint",
Doc: extractDoc(doc, "spanlint"),
Run: run(config),
Name: "spancheck",
Doc: extractDoc(doc, "spancheck"),
Flags: config.fs,
Run: run(config),
Requires: []*analysis.Analyzer{
ctrlflow.Analyzer,
inspect.Analyzer,
Expand Down
10 changes: 5 additions & 5 deletions spanlint_test.go → spancheck_test.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
package spanlint_test
package spancheck_test

import (
"regexp"
"testing"

"golang.org/x/tools/go/analysis/analysistest"

"github.com/jjti/go-spanlint"
"github.com/jjti/go-spancheck"
)

func Test(t *testing.T) {
t.Parallel()

for dir, config := range map[string]*spanlint.Config{
"base": spanlint.NewDefaultConfig(),
for dir, config := range map[string]*spancheck.Config{
"base": spancheck.NewConfig(),
"disableerrorchecks": {
EnableSetStatusCheck: true,
IgnoreSetStatusCheckSignatures: regexp.MustCompile("telemetry.Record"),
Expand All @@ -30,7 +30,7 @@ func Test(t *testing.T) {
} {
dir := dir
t.Run(dir, func(t *testing.T) {
analysistest.Run(t, "testdata/"+dir, spanlint.NewAnalyzer(config))
analysistest.Run(t, "testdata/"+dir, spancheck.NewAnalyzerWithConfig(config))
})
}
}
2 changes: 1 addition & 1 deletion testdata/base/go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/jjti/go-spanlint/testdata/base
module github.com/jjti/go-spancheck/testdata/base

go 1.21.3

Expand Down
2 changes: 1 addition & 1 deletion testdata/disableerrorchecks/disable_error_checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"context"
"errors"

"github.com/jjti/go-spanlint/testdata/disableerrorchecks/telemetry"
"github.com/jjti/go-spancheck/testdata/disableerrorchecks/telemetry"
"go.opentelemetry.io/otel"
)

Expand Down
2 changes: 1 addition & 1 deletion testdata/disableerrorchecks/go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/jjti/go-spanlint/testdata/disableerrorchecks
module github.com/jjti/go-spancheck/testdata/disableerrorchecks

go 1.21.3

Expand Down
2 changes: 1 addition & 1 deletion testdata/enableall/go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/jjti/go-spanlint/testdata/enableall
module github.com/jjti/go-spancheck/testdata/enableall

go 1.21.3

Expand Down
2 changes: 1 addition & 1 deletion testdata/enablechecks/go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/jjti/go-spanlint/testdata/enablechecks
module github.com/jjti/go-spancheck/testdata/enablechecks

go 1.21.3

Expand Down

0 comments on commit fd857b5

Please sign in to comment.