From dee3b15156e9d1a19b34208ae1dfc10d84395bea Mon Sep 17 00:00:00 2001 From: Aleksey Lobanov Date: Mon, 1 Jan 2024 18:58:04 +0000 Subject: [PATCH] feat: Iniital commit with pre-commit integrated --- .devcontainer/Dockerfile | 7 ++++ .devcontainer/devcontainer.json | 10 +++--- .gitignore | 1 + .pre-commit-config.yaml | 23 +++++++++++++ README.md | 14 +++++++- main.go | 58 +++++++++++++++++---------------- 6 files changed, 78 insertions(+), 35 deletions(-) create mode 100644 .devcontainer/Dockerfile create mode 100644 .pre-commit-config.yaml diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..0855471 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,7 @@ +FROM mcr.microsoft.com/devcontainers/go:1-1.21-bullseye +RUN sudo apt update && sudo apt install -y python3 python3-pip + +RUN go install -v github.com/go-critic/go-critic/cmd/gocritic@latest \ + && go install github.com/fzipp/gocyclo/cmd/gocyclo@latest\ + && go install golang.org/x/tools/cmd/goimports@latest\ + && sudo pip3 install pre-commit diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 7783fb1..4019a8a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,23 +3,21 @@ { "name": "Go", // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile - "image": "mcr.microsoft.com/devcontainers/go:1-1.21-bullseye", + "build": { + // Path is relative to the devcontainer.json file. + "dockerfile": "Dockerfile" + }, "features": { "ghcr.io/guiyomh/features/gotestsum:0": {} } - // Features to add to the dev container. More info: https://containers.dev/features. // "features": {}, - // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], - // Use 'postCreateCommand' to run commands after the container is created. // "postCreateCommand": "go version", - // Configure tool-specific properties. // "customizations": {}, - // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. // "remoteUser": "root" } diff --git a/.gitignore b/.gitignore index 3cb0fe4..6f137b7 100644 --- a/.gitignore +++ b/.gitignore @@ -198,3 +198,4 @@ cython_debug/ # .nfs files are created when an open file is removed but is still being accessed .nfs* +gogrep diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..a8f133c --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,23 @@ +repos: + - repo: https://github.com/dnephin/pre-commit-golang + rev: v0.5.1 + hooks: + - id: go-fmt + - id: go-vet + - id: go-lint + - id: go-imports + - id: go-cyclo + args: [-over=15] + - id: validate-toml + - id: no-go-testing + - id: golangci-lint + - id: go-critic + - id: go-unit-tests + - id: go-build + - id: go-mod-tidy + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace diff --git a/README.md b/README.md index 66cb35e..ba27a48 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,15 @@ # gogrep -Simple concurrent grep alternative \ No newline at end of file +Simple concurrent grep alternative + +# Usage + +TBD + + +# For developer +Simplest to use environment is already is VS Code Dev container. +Steps: + +1. Open folder in Dev Container +2. Run `pre-commit install`. This tool will validate *new* commits according to checks defined in `.pre-commit-config.yaml`. diff --git a/main.go b/main.go index dc413d1..ab7eb37 100644 --- a/main.go +++ b/main.go @@ -10,15 +10,18 @@ import ( "regexp" ) -const CHANNEL_BUFFERING = 10 +// ChannelBuffering is the size of file processing results queue +const ChannelBuffering = 10 +// FileMatchData contains grep results type FileMatchData struct { Path string LineIndexes []int Lines []string } -func ProcessSingleFile(re_pattern regexp.Regexp, path string, out chan FileMatchData) error { +// ProcessSingleFile processes file and send it Result to channel +func ProcessSingleFile(rePattern regexp.Regexp, path string, out chan FileMatchData) { file, err := os.Open(path) if err != nil { log.Fatal(err) @@ -28,45 +31,44 @@ func ProcessSingleFile(re_pattern regexp.Regexp, path string, out chan FileMatch res := FileMatchData{Path: path, LineIndexes: make([]int, 0), Lines: make([]string, 0)} scanner := bufio.NewScanner(file) // optionally, resize scanner's capacity for lines over 64K, see next example - cur_line_ind := 1 + curLineInd := 1 for scanner.Scan() { - line_text := scanner.Text() - if re_pattern.FindString(line_text) != "" { - res.LineIndexes = append(res.LineIndexes, cur_line_ind) - res.Lines = append(res.Lines, line_text) + lineText := scanner.Text() + if rePattern.FindString(lineText) != "" { + res.LineIndexes = append(res.LineIndexes, curLineInd) + res.Lines = append(res.Lines, lineText) } - cur_line_ind++ + curLineInd++ } if err := scanner.Err(); err != nil { - log.Fatal(err) + fmt.Printf("Error %v with file %v\n", err, path) } out <- res - return nil } func main() { - path_pattern := "git/hook" - re_path_pattern, err := regexp.Compile(path_pattern) + pathPattern := "git/hook" + rePathPattern, err := regexp.Compile(pathPattern) if err != nil { - fmt.Printf("Unable to compile path pattern Regexp: %v\n", path_pattern) + fmt.Printf("Unable to compile path pattern Regexp: %v\n", pathPattern) return } - text_pattern := "the commit" - re_text_pattern, err := regexp.Compile(text_pattern) + textPattern := "the commit" + reTextPattern, err := regexp.Compile(textPattern) if err != nil { - fmt.Printf("Unable to compile text pattern Regexp: %v\n", text_pattern) + fmt.Printf("Unable to compile text pattern Regexp: %v\n", textPattern) return } - processed_channel := make(chan FileMatchData, CHANNEL_BUFFERING) - total_files := 0 + processedChannel := make(chan FileMatchData, ChannelBuffering) + totalFiles := 0 err = filepath.Walk(".", func(path string, info fs.FileInfo, err error) error { if err != nil { fmt.Printf("prevent panic by handling failure accessing a path %q: %v\n", path, err) return err } - if re_path_pattern.FindString(path) == "" { + if rePathPattern.FindString(path) == "" { return nil } // if info.IsDir() && info.Name() == subDirToSkip { @@ -76,25 +78,25 @@ func main() { if info.IsDir() { return nil } - go ProcessSingleFile(*re_text_pattern, path, processed_channel) - total_files++ + go ProcessSingleFile(*reTextPattern, path, processedChannel) + totalFiles++ return nil }) - for ; total_files > 0; total_files-- { - cur_processed := <-processed_channel - if len(cur_processed.Lines) == 0 { + for ; totalFiles > 0; totalFiles-- { + curProcessed := <-processedChannel + if len(curProcessed.Lines) == 0 { continue } - fmt.Printf("%s:\n", cur_processed.Path) - for i := 0; i < len(cur_processed.Lines); i++ { - fmt.Printf("%d:%s\n", cur_processed.LineIndexes[i], cur_processed.Lines[i]) + fmt.Printf("%s:\n", curProcessed.Path) + for i := 0; i < len(curProcessed.Lines); i++ { + fmt.Printf("%d:%s\n", curProcessed.LineIndexes[i], curProcessed.Lines[i]) } fmt.Print("\n") } if err != nil { - fmt.Printf("error walking the path %q: %v\n", path_pattern, err) + fmt.Printf("error walking the path %q: %v\n", pathPattern, err) return } }