From ea3e2e508237625d7cce5fbb4ab9ca4980e02fb5 Mon Sep 17 00:00:00 2001 From: Gabriel Augendre Date: Mon, 7 Aug 2023 20:54:08 +0200 Subject: [PATCH] initial commit --- .envrc | 1 + .gitignore | 173 ++++++++++++++++++++++++++++++++++++++ .golangci.yaml | 32 +++++++ .pre-commit-config.yaml | 5 ++ .tool-versions | 2 + Makefile | 5 ++ cmd/cli/main.go | 4 + go.mod | 3 + lib/gordle/gordle.go | 36 ++++++++ lib/gordle/gordle_test.go | 38 +++++++++ 10 files changed, 299 insertions(+) create mode 100644 .envrc create mode 100644 .gitignore create mode 100644 .golangci.yaml create mode 100644 .pre-commit-config.yaml create mode 100644 .tool-versions create mode 100644 Makefile create mode 100644 cmd/cli/main.go create mode 100644 go.mod create mode 100644 lib/gordle/gordle.go create mode 100644 lib/gordle/gordle_test.go diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..25e93e7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,173 @@ +# Created by https://www.toptal.com/developers/gitignore/api/go,goland,macos +# Edit at https://www.toptal.com/developers/gitignore?templates=go,goland,macos + +### Go ### +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore +# +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Go workspace file +go.work + +### GoLand ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### GoLand Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +# https://plugins.jetbrains.com/plugin/7973-sonarlint +.idea/**/sonarlint/ + +# SonarQube Plugin +# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin +.idea/**/sonarIssues.xml + +# Markdown Navigator plugin +# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced +.idea/**/markdown-navigator.xml +.idea/**/markdown-navigator-enh.xml +.idea/**/markdown-navigator/ + +# Cache file creation bug +# See https://youtrack.jetbrains.com/issue/JBR-2257 +.idea/$CACHE_FILE$ + +# CodeStream plugin +# https://plugins.jetbrains.com/plugin/12206-codestream +.idea/codestream.xml + +# Azure Toolkit for IntelliJ plugin +# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij +.idea/**/azureSettings.xml + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### macOS Patch ### +# iCloud generated files +*.icloud + +# End of https://www.toptal.com/developers/gitignore/api/go,goland,macos +.idea diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 0000000..9fec5d7 --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,32 @@ +issues: + fix: true + max-issues-per-linter: 0 + max-same-issues: 0 +linters: + enable-all: true + disable: + - godox + - nlreturn + - exhaustruct + - depguard + - gofmt # gofumpt still enabled + - goimports # conflicts with gofumpt + # deprecated + - ifshort + - deadcode + - varcheck + - interfacer + - exhaustivestruct + - scopelint + - golint + - structcheck + - nosnakecase + - maligned +linters-settings: + varnamelen: + ignore-names: + - id + - db + ignore-decls: + - w http.ResponseWriter + - r *http.Request diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..5a5b46b --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,5 @@ +repos: + - repo: https://github.com/golangci/golangci-lint + rev: v1.53.3 + hooks: + - id: golangci-lint diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..c2bb354 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +go 1.20 +golangci-lint 1.53 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0360fe6 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +test: + go test ./... + +lint: + golangci-lint run \ No newline at end of file diff --git a/cmd/cli/main.go b/cmd/cli/main.go new file mode 100644 index 0000000..da29a2c --- /dev/null +++ b/cmd/cli/main.go @@ -0,0 +1,4 @@ +package main + +func main() { +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..fe84861 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/Crocmagnon/gordle + +go 1.20 diff --git a/lib/gordle/gordle.go b/lib/gordle/gordle.go new file mode 100644 index 0000000..e278432 --- /dev/null +++ b/lib/gordle/gordle.go @@ -0,0 +1,36 @@ +package gordle + +import ( + "bufio" + "errors" + "fmt" + "math/rand" + "strings" +) + +var ErrWordNotFound = errors.New("word not found with requested length") + +func GetWord(reader *strings.Reader, wordLength int) (string, error) { + var candidates []string + + scanner := bufio.NewScanner(reader) + for scanner.Scan() { + word := scanner.Text() + if len(word) == wordLength { + candidates = append(candidates, word) + } + } + + if err := scanner.Err(); err != nil { + return "", fmt.Errorf("reading from scanner: %w", err) + } + + candidatesCount := len(candidates) + if candidatesCount == 0 { + return "", ErrWordNotFound + } + + rnd := rand.Intn(candidatesCount) //nolint:gosec // No need for crypto here. + + return candidates[rnd], nil +} diff --git a/lib/gordle/gordle_test.go b/lib/gordle/gordle_test.go new file mode 100644 index 0000000..5cb5136 --- /dev/null +++ b/lib/gordle/gordle_test.go @@ -0,0 +1,38 @@ +package gordle_test + +import ( + "errors" + "strings" + "testing" + + "github.com/Crocmagnon/gordle/lib/gordle" +) + +func TestGetWord(t *testing.T) { + t.Parallel() + + tests := []struct { + length int + wantErr error + want string + }{ + {length: 4, wantErr: nil, want: "test"}, + {length: 5, wantErr: nil, want: "tests"}, + {length: 6, wantErr: gordle.ErrWordNotFound, want: ""}, + } + for _, test := range tests { + test := test + t.Run(test.want, func(t *testing.T) { + t.Parallel() + input := "test\ntests" + got, err := gordle.GetWord(strings.NewReader(input), test.length) + if !errors.Is(err, test.wantErr) { + t.Fatalf("got err %q want %q", test.wantErr, err) + } + + if got != test.want { + t.Errorf("got %q, want %q", got, test.want) + } + }) + } +}