Skip to content

Commit

Permalink
refactor: log viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
CarlJi committed Sep 5, 2024
1 parent 87a43a5 commit 3b548c2
Show file tree
Hide file tree
Showing 15 changed files with 216 additions and 97 deletions.
11 changes: 2 additions & 9 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ import (
"sigs.k8s.io/yaml"
)

// Config is the config for the using of reviewbot.
type Config struct {
GlobalDefaultConfig GlobalConfig `json:"globalDefaultConfig,omitempty"`
LogStorageConfig LogStorageConfig `json:"logStorageConfig,omitempty"`
ServerAddr string `json:"serverAddr,omitempty"`
GlobalDefaultConfig GlobalConfig `json:"globalDefaultConfig,omitempty"`

// CustomConfig is the custom linter config.
// e.g.
Expand Down Expand Up @@ -39,12 +38,6 @@ type GlobalConfig struct {
JavaStyleCheckRuleConfig string `json:"javastylecheckruleConfig,omitempty"`
}

type LogStorageConfig struct {
CustomRemoteConfigs map[string]any `json:"customRemoteConfigs"`
}

type GithubConfig struct{}

type Linter struct {
// Enable is whether to enable this linter, if false, linter still run but not report.
Enable *bool `json:"enable,omitempty"`
Expand Down
8 changes: 7 additions & 1 deletion internal/linters/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,17 @@ func CreateGithubChecks(ctx context.Context, a Agent, lintErrs map[string][]Lint
},
Output: &github.CheckRunOutput{
Title: github.String(fmt.Sprintf("%s found %d issues related to your changes", linterName, len(annotations))),
Summary: github.String(fmt.Sprintf("[full log ](%s)\n", a.LinterLogViewUrl) + Reference),
Annotations: annotations,
},
}

logURL := a.GenLogViewUrl()
if logURL == "" {
check.Output.Summary = github.String(Reference)
} else {
check.Output.Summary = github.String(fmt.Sprintf("[full log ](%s)\n", logURL) + Reference)
}

if len(annotations) > 0 {
check.Conclusion = github.String("failure")
} else {
Expand Down
1 change: 0 additions & 1 deletion internal/linters/go/gomodcheck/gomodcheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ func goModCheckHandler(ctx context.Context, a linters.Agent) error {
return err
}
return linters.Report(log, a, parsedOutput)

Check warning on line 29 in internal/linters/go/gomodcheck/gomodcheck.go

View check run for this annotation

qiniu-x / golangci-lint

internal/linters/go/gomodcheck/gomodcheck.go#L29

Function `Report` should pass the context parameter (contextcheck)

}

func goModCheckOutput(log *xlog.Logger, a linters.Agent) (map[string][]linters.LinterOutput, error) {
Expand Down
1 change: 1 addition & 0 deletions internal/linters/java/pmdcheck/pmdcheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func pmdCheckHandler(ctx context.Context, a linters.Agent) error {
a.LinterConfig.Args = append(append(a.LinterConfig.Args, javaFiles...), "-R", checkrulePath)
return linters.GeneralHandler(plog, a, linters.ExecRun, pmdcheckParser)
}

func argsApply(log *xlog.Logger, a linters.Agent) linters.Agent {
config := a.LinterConfig

Check warning on line 53 in internal/linters/java/pmdcheck/pmdcheck.go

View check run for this annotation

qiniu-x / golangci-lint

internal/linters/java/pmdcheck/pmdcheck.go#L53

import-shadowing: The name 'config' shadows an import name (revive)
if len(config.Command) == 1 && config.Command[0] == linterName {
Expand Down
22 changes: 10 additions & 12 deletions internal/linters/linters.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,12 @@ type LinterOutput struct {

// Agent knows necessary information in order to run linters.
type Agent struct {
// ID each linter execution has a unique id.
ID string
// Context is the context of the agent.
Context context.Context
// LogStorages is the way to contral log storage
LogStorage storage.Storage
// Storage knows how to store and retrieve the linter logs.
Storage storage.Storage
// Runner is the way to run the linter. like docker, local, etc.
Runner runner.Runner
// GitHubClient is the GitHub client.
Expand All @@ -120,12 +122,11 @@ type Agent struct {
LinterName string
// RepoDir is the repo directory.
RepoDir string
// LinterUuid is the uinque id of onece linter exec .
LinterUuid string
// LinterLogStoragePath is the path of log storage
LinterLogStoragePath string
// LinterLogStoragePath is the path of log storage
LinterLogViewUrl string

// GenLogKey generates the log key.
GenLogKey func() string
// GenLogViewUrl generates the log view url.
GenLogViewUrl func() string
}

const CommentFooter = `
Expand Down Expand Up @@ -181,12 +182,9 @@ func ExecRun(a Agent) ([]byte, error) {
return nil, fmt.Errorf("failed to read linter output: %w", err)
}

ctx := context.Background()
err = a.LogStorage.Writer(ctx, a.LinterLogStoragePath, output)
err = a.Storage.Write(a.Context, a.GenLogKey(), output)
if err != nil {
log.Errorf("write to storage was failed %v", err)
} else {
log.Info("write to storage was successful")
}

return output, nil
Expand Down
8 changes: 8 additions & 0 deletions internal/linters/linters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ import (
"context"
"errors"
"fmt"
"os"
"reflect"
"testing"

"github.com/qiniu/reviewbot/config"
"github.com/qiniu/reviewbot/internal/runner"
"github.com/qiniu/reviewbot/internal/storage"
"github.com/qiniu/x/xlog"
)

Expand Down Expand Up @@ -227,6 +229,12 @@ func TestExecRun(t *testing.T) {
}
for _, tc := range tcs {
t.Run(tc.id, func(t *testing.T) {
storage, err := storage.NewLocalStorage(os.TempDir())
if err != nil {
t.Errorf("failed to create local storage: %v", err)
}
tc.input.Storage = storage
tc.input.GenLogKey = func() string { return "test" }
tc.input.Runner = runner.NewLocalRunner()
tc.input.LinterConfig.Modifier = config.NewBaseModifier()
tc.input.Context = context.WithValue(context.Background(), config.EventGUIDKey, "test")
Expand Down
7 changes: 5 additions & 2 deletions internal/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,17 @@ import (
"github.com/qiniu/x/xlog"
)

// Runner defines the interface for how to run the linter.
type Runner interface {
// Prepare prepares the linter for running.
Prepare(ctx context.Context, cfg *config.Linter) error

// Run runs the linter and returns the output.
Run(ctx context.Context, cfg *config.Linter) (io.ReadCloser, error)
}

// LocalRunner is a runner that runs the linter locally.
type LocalRunner struct {
}
type LocalRunner struct{}

func NewLocalRunner() Runner {
return &LocalRunner{}
Expand Down
31 changes: 18 additions & 13 deletions internal/storage/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,33 @@ import (
"fmt"
"os"
"path/filepath"
"sync"

"github.com/qiniu/x/log"
)

type LocalStorage struct {
mu sync.Mutex
rootDir string
}

func NewLocalStorage() Storage {
return &LocalStorage{}
func NewLocalStorage(rootDir string) (Storage, error) {
rootDir, err := filepath.Abs(rootDir)
if err != nil {
return nil, fmt.Errorf("failed to get absolute path: %w", err)
}
if err := os.MkdirAll(rootDir, 0o755); err != nil {
return nil, fmt.Errorf("failed to make log dir: %w", err)
}
return &LocalStorage{rootDir: rootDir}, nil
}

func (*LocalStorage) Writer(ctx context.Context, path string, content []byte) error {
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
func (l *LocalStorage) Write(ctx context.Context, path string, content []byte) error {
logFile := filepath.Join(l.rootDir, path, DefaultLogName)
log.Infof("writing log to %s", logFile)
if err := os.MkdirAll(filepath.Dir(logFile), 0o755); err != nil {
log.Errorf("failed to make log dir: %v", err)
}
dir, _ := os.Getwd()
log.Infof("pwd: %s", dir)
file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)

file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o644)
if err != nil {
return fmt.Errorf("failed to open file: %w", err)
}
Expand All @@ -42,14 +49,12 @@ func (*LocalStorage) Writer(ctx context.Context, path string, content []byte) er
return nil
}

func (g *LocalStorage) Reader(ctx context.Context, path string) ([]byte, error) {
filePath := path
func (g *LocalStorage) Read(ctx context.Context, path string) ([]byte, error) {

Check warning on line 52 in internal/storage/file.go

View check run for this annotation

qiniu-x / golangci-lint

internal/storage/file.go#L52

receiver-naming: receiver name g should be consistent with previous receiver name l for LocalStorage (revive)
filePath := filepath.Join(g.rootDir, path, DefaultLogName)
if _, err := os.Stat(filePath); os.IsNotExist(err) {
return nil, fmt.Errorf("file does not exist: %s", filePath)
}

g.mu.Lock()
defer g.mu.Unlock()
data, err := os.ReadFile(filePath)
if err != nil {
return nil, fmt.Errorf("error reading file: %w", err)
Expand Down
19 changes: 19 additions & 0 deletions internal/storage/git.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package storage

import (
"context"
)

type GitStorage struct{}

func NewGitStorage() (Storage, error) {
return &GitStorage{}, nil
}

func (g *GitStorage) Write(ctx context.Context, key string, content []byte) error {

Check warning on line 13 in internal/storage/git.go

View check run for this annotation

qiniu-x / golangci-lint

internal/storage/git.go#L13

unused-receiver: method receiver 'g' is not referenced in method's body, consider removing or renaming it as _ (revive)
return nil
}

func (g *GitStorage) Read(ctx context.Context, key string) ([]byte, error) {

Check warning on line 17 in internal/storage/git.go

View check run for this annotation

qiniu-x / golangci-lint

internal/storage/git.go#L17

unused-receiver: method receiver 'g' is not referenced in method's body, consider removing or renaming it as _ (revive)
return nil, nil
}
21 changes: 0 additions & 21 deletions internal/storage/github.go

This file was deleted.

21 changes: 21 additions & 0 deletions internal/storage/s3.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package storage

import "context"

type S3Storage struct {
credential string
}

func NewS3Storage(credential string) (Storage, error) {
return &S3Storage{
credential: credential,
}, nil
}

func (s *S3Storage) Write(ctx context.Context, key string, content []byte) error {

Check warning on line 15 in internal/storage/s3.go

View check run for this annotation

qiniu-x / golangci-lint

internal/storage/s3.go#L15

unused-receiver: method receiver 's' is not referenced in method's body, consider removing or renaming it as _ (revive)
return nil
}

func (s *S3Storage) Read(ctx context.Context, key string) ([]byte, error) {

Check warning on line 19 in internal/storage/s3.go

View check run for this annotation

qiniu-x / golangci-lint

internal/storage/s3.go#L19

unused-receiver: method receiver 's' is not referenced in method's body, consider removing or renaming it as _ (revive)
return nil, nil
}
10 changes: 8 additions & 2 deletions internal/storage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ package storage
import "context"

type Storage interface {
Writer(ctx context.Context, path string, content []byte) error
// Write writes the content to the specified key.
Write(ctx context.Context, key string, content []byte) error

Reader(ctx context.Context, path string) ([]byte, error)
// Read reads the content from the specified key.
Read(ctx context.Context, key string) ([]byte, error)
}

const (
DefaultLogName = "log.txt"
)
65 changes: 65 additions & 0 deletions internal/storage/storage_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package storage_test

import (
"context"
"os"
"path/filepath"
"testing"

"github.com/qiniu/reviewbot/internal/storage"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestFileStorage(t *testing.T) {
tempDir, err := os.MkdirTemp("", "file_storage_test")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
fs, err := storage.NewLocalStorage(tempDir)
require.NoError(t, err)

t.Run("Write and Read", func(t *testing.T) {
ctx := context.Background()
content := []byte("测试内容")
path := "test.txt"
err := fs.Write(ctx, path, content)
require.NoError(t, err)
readContent, err := fs.Read(ctx, path)
require.NoError(t, err)
assert.Equal(t, content, readContent)
})

t.Run("Read Non-existent File", func(t *testing.T) {
ctx := context.Background()
_, err := fs.Read(ctx, "non_existent.txt")
require.Error(t, err)
})

t.Run("Write to Non-existent Directory", func(t *testing.T) {
ctx := context.Background()
content := []byte("测试内容")
path := filepath.Join("non", "existent", "dir", "test.txt")

err := fs.Write(ctx, path, content)
require.NoError(t, err)

readContent, err := fs.Read(ctx, path)
require.NoError(t, err)
require.Equal(t, content, readContent)
})

t.Run("Overwrite Existing File", func(t *testing.T) {
ctx := context.Background()
path := "overwrite.txt"
err := fs.Write(ctx, path, []byte("原始内容"))
require.NoError(t, err)

newContent := []byte("新内容")
err = fs.Write(ctx, path, newContent)
require.NoError(t, err)

readContent, err := fs.Read(ctx, path)
require.NoError(t, err)
require.Equal(t, newContent, readContent)
})
}
Loading

0 comments on commit 3b548c2

Please sign in to comment.