Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
codecrafters-bot authored Aug 29, 2024
0 parents commit 6b30e47
Show file tree
Hide file tree
Showing 21 changed files with 430 additions and 0 deletions.
29 changes: 29 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Publish

on:
push:
tags:
- "v*"

jobs:
publish_tester:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Unshallow
run: git fetch --prune --unshallow

- name: Set up Go
uses: actions/setup-go@v1
with:
go-version: 1.17.x

- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v1
with:
version: v0.177.0
args: release -f main.goreleaser.yml --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24 changes: 24 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Test

on: push

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
lfs: true

- name: Set up Go
uses: actions/setup-go@v1
with:
go-version: 1.17.x

- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: '3.8'

- run: make test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist
27 changes: 27 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.PHONY: release build test test_with_bash copy_course_file

current_version_number := $(shell git tag --list "v*" | sort -V | tail -n 1 | cut -c 2-)
next_version_number := $(shell echo $$(($(current_version_number)+1)))

release:
git tag v$(next_version_number)
git push origin main v$(next_version_number)

build:
go build -o dist/main.out ./cmd/tester

test:
TESTER_DIR=$(shell pwd) go test -v ./internal/

test_and_watch:
onchange '**/*' -- go test -v ./internal/

copy_course_file:
hub api \
repos/codecrafters-io/build-your-own-grep/contents/course-definition.yml \
| jq -r .content \
| base64 -d \
> internal/test_helpers/course_definition.yml

update_tester_utils:
go get -u github.com/codecrafters-io/tester-utils
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# <fill_in_challenge_name> Challenge Tester

This is a program that validates your progress on the "Build your own grep" challenge.

## Requirements for binary

- Following environment variables:
- `CODECRAFTERS_SUBMISSION_DIR` - root of the user's code submission
- `CODECRAFTERS_TEST_CASES_JSON` - test cases in JSON format

## User code requirements

- A binary named `<fill_in_script_name>.sh` that executes the program.
- A file named `codecrafters.yml`, with the following values:
- `debug`
23 changes: 23 additions & 0 deletions cmd/tester/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import (
"os"
"strings"

"github.com/codecrafters-io/grep-tester/internal"
)

func main() {
os.Exit(internal.RunCLI(envMap()))
}

func envMap() map[string]string {
result := make(map[string]string)
for _, keyVal := range os.Environ() {
split := strings.SplitN(keyVal, "=", 2)
key, val := split[0], split[1]
result[key] = val
}

return result
}
18 changes: 18 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module github.com/codecrafters-io/grep-tester

go 1.20

require github.com/codecrafters-io/tester-utils v0.2.15

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.8.4 // indirect
golang.org/x/sys v0.18.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
39 changes: 39 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
github.com/codecrafters-io/tester-utils v0.2.1 h1:+bdZLJhFMWcf+/E3C4NlGsIvxvsyBWlrrqceXRFyu6E=
github.com/codecrafters-io/tester-utils v0.2.1/go.mod h1:BeSLyqBpFxUwIm41QlnuRG7ZsabBXWE2Ga3LMFUXAPM=
github.com/codecrafters-io/tester-utils v0.2.10 h1:Xpu6wzgpRpiZPFNGWMRcJXwAZZ0Yb5Mv6IDOR319f+s=
github.com/codecrafters-io/tester-utils v0.2.10/go.mod h1:BeSLyqBpFxUwIm41QlnuRG7ZsabBXWE2Ga3LMFUXAPM=
github.com/codecrafters-io/tester-utils v0.2.15 h1:d6lbr1nVkZ4+G55E47bG3bf1lWiMLOUZy5EiHwX2SsE=
github.com/codecrafters-io/tester-utils v0.2.15/go.mod h1:BeSLyqBpFxUwIm41QlnuRG7ZsabBXWE2Ga3LMFUXAPM=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
18 changes: 18 additions & 0 deletions internal/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package internal

import (
"fmt"

testerutils "github.com/codecrafters-io/tester-utils"
)

func RunCLI(env map[string]string) int {
tester, err := testerutils.NewTester(env, testerDefinition)

if err != nil {
fmt.Printf("%s", err)
return 1
}

return tester.RunCLI()
}
39 changes: 39 additions & 0 deletions internal/stage_init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package internal

import (
"fmt"

"github.com/codecrafters-io/tester-utils/test_case_harness"
)

// Example from the grep course
func testInit(stageHarness *test_case_harness.TestCaseHarness) error {
// should exit with 0: echo "dog" | grep -E "d"
stageHarness.Logger.Infof("$ echo \"%s\" | ./script.sh -E \"%s\"", "dog", "d")

result, err := stageHarness.Executable.RunWithStdin([]byte("dog"), "-E", "d")
if err != nil {
return err
}

if result.ExitCode != 0 {
return fmt.Errorf("expected exit code %v, got %v", 0, result.ExitCode)
}

stageHarness.Logger.Successf("✓ Received exit code %d.", 0)

// should exit with 1: echo "dog" | grep -E "d"
stageHarness.Logger.Infof("$ echo \"%s\" | ./script.sh -E \"%s\"", "dog", "f")

result, err = stageHarness.Executable.RunWithStdin([]byte("dog"), "-E", "f")
if err != nil {
return err
}

if result.ExitCode != 1 {
return fmt.Errorf("expected exit code %v, got %v", 1, result.ExitCode)
}

stageHarness.Logger.Successf("✓ Received exit code %d.", 1)
return nil
}
25 changes: 25 additions & 0 deletions internal/stages_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package internal

import (
"testing"

tester_utils_testing "github.com/codecrafters-io/tester-utils/testing"
)

func TestStages(t *testing.T) {
testCases := map[string]tester_utils_testing.TesterOutputTestCase{
"literal_character": {
UntilStageSlug: "init",
CodePath: "./test_helpers/scenarios/init/failure",
ExpectedExitCode: 1,
StdoutFixturePath: "./test_helpers/fixtures/init/failure",
NormalizeOutputFunc: normalizeTesterOutput,
},
}

tester_utils_testing.TestTesterOutput(t, testerDefinition, testCases)
}

func normalizeTesterOutput(testerOutput []byte) []byte {
return testerOutput
}
120 changes: 120 additions & 0 deletions internal/test_helpers/course_definition.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# This should be replaced with your course's course-definition.yml

# Used in your course's URL: https://app.codecrafters.io/courses/<slug>
# Example: "redis"
slug: "your_course_slug"

# The name of your course. This will be displayed in the course catalog, and on other course pages.
# Example: "Build your own Redis"
name: "Build your own something"

# A short name for your course, this'll be used in copy like emails.
# Example: "Redis"
short_name: "dummy"

# The release status for your course.
#
# - alpha: Only visible to yourself and CodeCrafters staff.
# - beta: Visible to all CodeCrafters users, but with a "beta" label.
# - live: Visible to all CodeCrafters users, no label.
#
# Allowed values: "alpha", "beta", "live"
release_status: "alpha"

# This is shown on the course overview page. Markdown supported, recommended length ~30 words.
#
# Recommended format:
#
# > In this challenge, you'll build ABC that's capable of D, E, F and G. Along the way, we'll learn about X, Y, Z and more.
#
# Example:
#
# > In this challenge, you'll build a toy Redis clone that's capable of handling basic commands like PING, GET
# > and SET. Along the way, we'll learn about event loops, the Redis Protocol and more.
description_md: |-
Add a description for your course here.
# This is shown on the catalog. Plaintext only, recommended length ~10 words.
#
# Recommended format:
#
# > Learn about X, Y, Z and more
#
# Example:
#
# > Learn about TCP servers, the Redis protocol and more
#
# **TODO**: Remove _md suffix since markdown isn't supported
short_description_md: |-
Add a short description for your course here.
# The percentage of users who complete your course. We'll calculate this automatically in the future, safe to ignore for now.
completion_percentage: 15

# The languages that your course supports.
languages:
- slug: "go"
- slug: "python"
- slug: "rust"

marketing:
# Shown in the catalog.
#
# Recommended guidelines:
#
# - "easy": < 2h of work for an experienced developer
# - "medium": > 6h of work for an experienced developer
# - "hard": > 6h of work for an experienced developer
#
# Allowed values: "easy", "medium", "hard"
difficulty: medium

# This is shown as an example when users suggest extensions to your course.
# Example: "Persistence" (from the Redis challenge)
sample_extension_idea_title: "My course extension idea"

# This is shown as an example when users suggest extensions to your course.
# Example: "A Redis server that can read and write .rdb files" (from the Redis challenge)
sample_extension_idea_description: "A description for my course extension idea"

# These are some default testimonials that you can use. Feel free to switch these out with your own.
testimonials:
- author_name: "Ananthalakshmi Sankar"
author_description: "Automation Engineer at Apple"
author_avatar: "https://codecrafters.io/images/external/testimonials/oxta.jpeg"
link: "https://github.com/anu294"
text: "There are few sites I like as much that have a step by step guide. The real-time feedback is so good, it's creepy!"

- author_name: "Patrick Burris"
author_description: "Senior Software Developer, CenturyLink"
author_avatar: "https://codecrafters.io/images/external/testimonials/patrick-burris.jpeg"
link: "https://github.com/Jumballaya"
text: |-
I think the instant feedback right there in the git push is really cool.
Didn't even know that was possible!
stages:
- slug: "init"
name: "Match a literal character"
difficulty: very_easy
description_md: |-
In this stage, we'll handle the simplest regex possible: a single character.
**Example:** `a` should match "apple", but not "dog".
Your program will be executed like this:
```bash
$ echo "apple" | ./script.sh -E "a"
```
The `-E` flag instructs `grep` to interprets patterns as extended regular expressions (with support
for metacharacters like `+`, `?` etc.). We'll use this flag in all stages.
You program must [exit](https://en.wikipedia.org/wiki/Exit_status) with 0 if the character is found, and 1 if not.
marketing_md: |-
In this stage, we'll handle the simplest regex possible: a single character.
**Example:**
`a` should match "apple", but not "dog".
6 changes: 6 additions & 0 deletions internal/test_helpers/fixtures/init/failure
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[stage-1] Running tests for Stage #1: init
[stage-1] $ echo "dog" | ./script.sh -E "d"
[stage-1] ✓ Received exit code 0.
[stage-1] $ echo "dog" | ./script.sh -E "f"
[stage-1] expected exit code 1, got 0
[stage-1] Test failed (try setting 'debug: true' in your codecrafters.yml to see more details)
Loading

0 comments on commit 6b30e47

Please sign in to comment.