Skip to content

Commit

Permalink
Setup golines checker (#116)
Browse files Browse the repository at this point in the history
Make sure that CI catches files that have not been formatted by
`golines`.
Add a script that does the formatting and ignores autogenerated files.

Both idea and vscode will reformat a generated file if you save it.
Since golines does not offer a good way to ignore these files correctly.

Here is the CI detecting a poorly formatted file:
https://github.com/xmtp/xmtpd/actions/runs/10564716546/job/29267709565
  • Loading branch information
mkysel authored Aug 26, 2024
1 parent 3879604 commit 4dc7b3d
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 26 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,8 @@ jobs:
uses: golangci/golangci-lint-action@v3
with:
args: --timeout=5m --config .golangci.yaml
- run: go install github.com/segmentio/golines
- name: golines
uses: nickcharlton/diff-check@main
with:
command: dev/lint-golines
45 changes: 45 additions & 0 deletions .idea/watcherTasks.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions dev/lint-golines
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
set -e

golines -w --ignored-dirs=proto --ignored-dirs=mocks --ignored-dirs=abis --ignored-dirs=queries .
24 changes: 12 additions & 12 deletions pkg/config/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,29 @@ type ApiOptions struct {
}

type ContractsOptions struct {
RpcUrl string `long:"rpc-url" description:"Blockchain RPC URL"`
NodesContractAddress string `long:"nodes-address" description:"Node contract address"`
RpcUrl string `long:"rpc-url" description:"Blockchain RPC URL"`
NodesContractAddress string `long:"nodes-address" description:"Node contract address"`
MessagesContractAddress string `long:"messages-address" description:"Message contract address"`
RefreshInterval time.Duration `long:"refresh-interval" description:"Refresh interval" default:"60s"`
RefreshInterval time.Duration `long:"refresh-interval" description:"Refresh interval" default:"60s"`
}

type DbOptions struct {
ReaderConnectionString string `long:"reader-connection-string" description:"Reader connection string"`
WriterConnectionString string `long:"writer-connection-string" description:"Writer connection string" required:"true"`
ReadTimeout time.Duration `long:"read-timeout" description:"Timeout for reading from the database" default:"10s"`
WriteTimeout time.Duration `long:"write-timeout" description:"Timeout for writing to the database" default:"10s"`
MaxOpenConns int `long:"max-open-conns" description:"Maximum number of open connections" default:"80"`
WaitForDB time.Duration `long:"wait-for" description:"wait for DB on start, up to specified duration"`
WriterConnectionString string `long:"writer-connection-string" description:"Writer connection string" required:"true"`
ReadTimeout time.Duration `long:"read-timeout" description:"Timeout for reading from the database" default:"10s"`
WriteTimeout time.Duration `long:"write-timeout" description:"Timeout for writing to the database" default:"10s"`
MaxOpenConns int `long:"max-open-conns" description:"Maximum number of open connections" default:"80"`
WaitForDB time.Duration `long:"wait-for" description:"wait for DB on start, up to specified duration"`
}

type ServerOptions struct {
LogLevel string `short:"l" long:"log-level" description:"Define the logging level, supported strings are: DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL, and their lower-case forms." default:"INFO"`
LogLevel string `short:"l" long:"log-level" description:"Define the logging level, supported strings are: DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL, and their lower-case forms." default:"INFO"`
//nolint:staticcheck
LogEncoding string `long:"log-encoding" description:"Log encoding format. Either console or json" choice:"console" choice:"json" default:"console"`
LogEncoding string ` long:"log-encoding" description:"Log encoding format. Either console or json" default:"console" choice:"console"`

PrivateKeyString string `long:"private-key" description:"Private key to use for the node"`

API ApiOptions `group:"API Options" namespace:"api"`
DB DbOptions `group:"Database Options" namespace:"db"`
API ApiOptions `group:"API Options" namespace:"api"`
DB DbOptions `group:"Database Options" namespace:"db"`
Contracts ContractsOptions `group:"Contracts Options" namespace:"contracts"`
}
6 changes: 5 additions & 1 deletion pkg/indexer/blockchain/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ import (

// Construct a raw blockchain listener that can be used to listen for events across many contract event types
type LogStreamBuilder interface {
ListenForContractEvent(fromBlock uint64, contractAddress common.Address, topic common.Hash) <-chan types.Log
ListenForContractEvent(
fromBlock uint64,
contractAddress common.Address,
topic common.Hash,
) <-chan types.Log
Build() (LogStreamer, error)
}

Expand Down
14 changes: 12 additions & 2 deletions pkg/indexer/blockchain/rpcLogStreamer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ import (
// May be unwise or flaky and we may need to reconsider
const RPC_URL = "https://nodes.mewapi.io/rpc/eth"

func buildStreamer(t *testing.T, client ChainClient, fromBlock int, address common.Address, topic common.Hash) (*RpcLogStreamer, chan types.Log) {
func buildStreamer(
t *testing.T,
client ChainClient,
fromBlock int,
address common.Address,
topic common.Hash,
) (*RpcLogStreamer, chan types.Log) {
log, err := zap.NewDevelopment()
require.NoError(t, err)
channel := make(chan types.Log)
Expand All @@ -35,7 +41,11 @@ func buildStreamer(t *testing.T, client ChainClient, fromBlock int, address comm
func TestBuilder(t *testing.T) {
builder := NewRpcLogStreamBuilder(RPC_URL, testutils.NewLog(t))

listenerChannel := builder.ListenForContractEvent(1, testutils.RandomAddress(), []common.Hash{testutils.RandomLogTopic()})
listenerChannel := builder.ListenForContractEvent(
1,
testutils.RandomAddress(),
[]common.Hash{testutils.RandomLogTopic()},
)
require.NotNil(t, listenerChannel)

streamer, err := builder.Build()
Expand Down
4 changes: 2 additions & 2 deletions pkg/indexer/indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ func indexLogs(
time.Sleep(100 * time.Millisecond)
continue Retry
}
} else {
logger.Info("Stored log", zap.Uint64("blockNumber", event.BlockNumber))
} else {
logger.Info("Stored log", zap.Uint64("blockNumber", event.BlockNumber))
}
break Retry

Expand Down
10 changes: 6 additions & 4 deletions pkg/indexer/indexer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@ func TestIndexLogsRetryableError(t *testing.T) {
// Will fail for the first call with a retryable error and a non-retryable error on the second call
attemptNumber := 0

logStorer.EXPECT().StoreLog(mock.Anything, event).RunAndReturn(func(ctx context.Context, log types.Log) storer.LogStorageError {
attemptNumber++
return storer.NewLogStorageError(errors.New("retryable error"), attemptNumber < 2)
})
logStorer.EXPECT().
StoreLog(mock.Anything, event).
RunAndReturn(func(ctx context.Context, log types.Log) storer.LogStorageError {
attemptNumber++
return storer.NewLogStorageError(errors.New("retryable error"), attemptNumber < 2)
})
channel <- event

go indexLogs(context.Background(), channel, testutils.NewLog(t), logStorer)
Expand Down
7 changes: 6 additions & 1 deletion pkg/tracing/tracing.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ func Stop() {

// Wrap executes action in the context of a span.
// Tags the span with the error if action returns one.
func Wrap(ctx context.Context, log *zap.Logger, operation string, action func(context.Context, *zap.Logger, Span) error) error {
func Wrap(
ctx context.Context,
log *zap.Logger,
operation string,
action func(context.Context, *zap.Logger, Span) error,
) error {
span, ctx := tracer.StartSpanFromContext(ctx, operation)
defer span.Finish()
log = Link(span, log.With(zap.String("span", operation)))
Expand Down
24 changes: 20 additions & 4 deletions pkg/utils/sid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ func TestGetNodeID(t *testing.T) {

func TestGetSequenceID(t *testing.T) {
sid := uint64(0b0000000000000001111111111111111111111111111111111111111111111111)
require.Equal(t, int64(0b0000000000000000111111111111111111111111111111111111111111111111), SequenceID(sid))
require.Equal(
t,
int64(0b0000000000000000111111111111111111111111111111111111111111111111),
SequenceID(sid),
)
sid = uint64(0b0000000000000001000000000000000000000000000000000000000000000000)
require.Equal(t, int64(0), SequenceID(sid))
sid = uint64(0b0000000000000001000000000000000000000000000000000000000000000001)
Expand All @@ -41,11 +45,23 @@ func TestGetSequenceID(t *testing.T) {
func TestGetSID(t *testing.T) {
nodeID := uint16(1)
sequenceID := int64(1)
require.Equal(t, uint64(0b0000000000000001000000000000000000000000000000000000000000000001), SID(nodeID, sequenceID))
require.Equal(
t,
uint64(0b0000000000000001000000000000000000000000000000000000000000000001),
SID(nodeID, sequenceID),
)
nodeID = uint16(1)
sequenceID = int64(0)
require.Equal(t, uint64(0b0000000000000001000000000000000000000000000000000000000000000000), SID(nodeID, sequenceID))
require.Equal(
t,
uint64(0b0000000000000001000000000000000000000000000000000000000000000000),
SID(nodeID, sequenceID),
)
nodeID = uint16(0)
sequenceID = int64(1)
require.Equal(t, uint64(0b0000000000000000000000000000000000000000000000000000000000000001), SID(nodeID, sequenceID))
require.Equal(
t,
uint64(0b0000000000000000000000000000000000000000000000000000000000000001),
SID(nodeID, sequenceID),
)
}

0 comments on commit 4dc7b3d

Please sign in to comment.