diff --git a/compiled_starters/ocaml/.codecrafters/compile.sh b/compiled_starters/ocaml/.codecrafters/compile.sh new file mode 100755 index 00000000..297f95d1 --- /dev/null +++ b/compiled_starters/ocaml/.codecrafters/compile.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script is used to compile your program on CodeCrafters +# +# This runs before .codecrafters/run.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +dune build --build-dir /tmp/codecrafters-build-redis-ocaml diff --git a/compiled_starters/ocaml/.codecrafters/run.sh b/compiled_starters/ocaml/.codecrafters/run.sh new file mode 100755 index 00000000..9951c7c0 --- /dev/null +++ b/compiled_starters/ocaml/.codecrafters/run.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script is used to run your program on CodeCrafters +# +# This runs after .codecrafters/compile.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +exec /tmp/codecrafters-build-redis-ocaml/default/main.exe "$@" diff --git a/compiled_starters/ocaml/.gitattributes b/compiled_starters/ocaml/.gitattributes new file mode 100644 index 00000000..176a458f --- /dev/null +++ b/compiled_starters/ocaml/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/compiled_starters/ocaml/.ocamlformat b/compiled_starters/ocaml/.ocamlformat new file mode 100644 index 00000000..a499fbc0 --- /dev/null +++ b/compiled_starters/ocaml/.ocamlformat @@ -0,0 +1 @@ +profile = default \ No newline at end of file diff --git a/compiled_starters/ocaml/README.md b/compiled_starters/ocaml/README.md new file mode 100644 index 00000000..fc59280f --- /dev/null +++ b/compiled_starters/ocaml/README.md @@ -0,0 +1,34 @@ +![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/redis.png) + +This is a starting point for OCaml solutions to the +["Build Your Own Redis" Challenge](https://codecrafters.io/challenges/redis). + +In this challenge, you'll build a toy Redis clone that's capable of handling +basic commands like `PING`, `SET` and `GET`. Along the way we'll learn about +event loops, the Redis protocol and more. + +**Note**: If you're viewing this repo on GitHub, head over to +[codecrafters.io](https://codecrafters.io) to try the challenge. + +# Passing the first stage + +The entry point for your Redis implementation is in `src/main.ml`. Study and +uncomment the relevant code, and push your changes to pass the first stage: + +```sh +git add . +git commit -m "pass 1st stage" # any msg +git push origin master +``` + +That's all! + +# Stage 2 & beyond + +Note: This section is for stages 2 and beyond. + +1. Ensure you have `dune` installed locally +1. Run `./your_program.sh` to run your Redis server, which is implemented in + `src/main.ml`. +1. Commit your changes and run `git push origin master` to submit your solution + to CodeCrafters. Test output will be streamed to your terminal. diff --git a/compiled_starters/ocaml/codecrafters.yml b/compiled_starters/ocaml/codecrafters.yml new file mode 100644 index 00000000..d6ff6a7a --- /dev/null +++ b/compiled_starters/ocaml/codecrafters.yml @@ -0,0 +1,11 @@ +# Set this to true if you want debug logs. +# +# These can be VERY verbose, so we suggest turning them off +# unless you really need them. +debug: false + +# Use this to change the OCaml version used to run your code +# on Codecrafters. +# +# Available versions: ocaml-5.2.0 +language_pack: ocaml-5.2.0 diff --git a/compiled_starters/ocaml/codecrafters_redis.opam b/compiled_starters/ocaml/codecrafters_redis.opam new file mode 100644 index 00000000..6240bb18 --- /dev/null +++ b/compiled_starters/ocaml/codecrafters_redis.opam @@ -0,0 +1,27 @@ +# This file is generated by dune, edit dune-project instead +opam-version: "2.0" +version: "0.1" +synopsis: "Starter code for the Build your own Redis challenge" +maintainer: ["CodeCrafters "] +authors: ["CodeCrafters "] +license: "MIT" +homepage: "https://codecrafters.io" +bug-reports: "https://github.com/codecrafters-io/build-your-own-redis/issues" +depends: [ + "dune" {>= "3.16"} + "odoc" {with-doc} +] +build: [ + ["dune" "subst"] {dev} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] +] diff --git a/compiled_starters/ocaml/dune b/compiled_starters/ocaml/dune new file mode 100644 index 00000000..3e3209d2 --- /dev/null +++ b/compiled_starters/ocaml/dune @@ -0,0 +1,5 @@ +(include_subdirs unqualified) + +(executable + (name main) + (libraries unix)) diff --git a/compiled_starters/ocaml/dune-project b/compiled_starters/ocaml/dune-project new file mode 100644 index 00000000..4394d358 --- /dev/null +++ b/compiled_starters/ocaml/dune-project @@ -0,0 +1,17 @@ +(lang dune 3.16) + +(name codecrafters_redis) + +(generate_opam_files true) + +(package + (name codecrafters_redis) + (maintainers "CodeCrafters ") + (authors "CodeCrafters ") + (synopsis "Starter code for the Build your own Redis challenge") + (homepage "https://codecrafters.io") + (bug_reports + "https://github.com/codecrafters-io/build-your-own-redis/issues") + (license "MIT") + (allow_empty true) + (version 0.1)) diff --git a/compiled_starters/ocaml/src/main.ml b/compiled_starters/ocaml/src/main.ml new file mode 100644 index 00000000..f1fe0aa5 --- /dev/null +++ b/compiled_starters/ocaml/src/main.ml @@ -0,0 +1,16 @@ +open Unix + +let () = + (* You can use print statements as follows for debugging, they'll be visible when running tests. *) + Printf.eprintf "Logs from your program will appear here!\n"; + + (* Create a TCP server socket *) + let server_socket = socket PF_INET SOCK_STREAM 0 in + setsockopt server_socket SO_REUSEADDR true; + bind server_socket (ADDR_INET (inet_addr_of_string "127.0.0.1", 6379)); + listen server_socket 1; + + (* Uncomment this block to pass the first stage *) + (* let (client_socket, _) = accept server_socket in *) + (* close client_socket; *) + (* close server_socket *) diff --git a/compiled_starters/ocaml/your_program.sh b/compiled_starters/ocaml/your_program.sh new file mode 100755 index 00000000..6c4a17fa --- /dev/null +++ b/compiled_starters/ocaml/your_program.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# +# Use this script to run your program LOCALLY. +# +# Note: Changing this script WILL NOT affect how CodeCrafters runs your program. +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit early if any commands fail + +# Copied from .codecrafters/compile.sh +# +# - Edit this to change how your program compiles locally +# - Edit .codecrafters/compile.sh to change how your program compiles remotely +( + cd "$(dirname "$0")" # Ensure compile steps are run within the repository directory + dune build --build-dir /tmp/codecrafters-build-redis-ocaml +) + +# Copied from .codecrafters/run.sh +# +# - Edit this to change how your program runs locally +# - Edit .codecrafters/run.sh to change how your program runs remotely +exec /tmp/codecrafters-build-redis-ocaml/default/main.exe "$@" diff --git a/dockerfiles/ocaml-5.2.0.Dockerfile b/dockerfiles/ocaml-5.2.0.Dockerfile new file mode 100644 index 00000000..0e413091 --- /dev/null +++ b/dockerfiles/ocaml-5.2.0.Dockerfile @@ -0,0 +1,32 @@ +# syntax=docker/dockerfile:1.7-labs +FROM ocaml/opam:alpine-3.20-ocaml-5.2 + +# The image uses opam as the user, so let's set OPAMROOT to re-use whatever is already built +ENV OPAMROOT /home/opam/.opam + +# Ensures the container is re-built if dune/dune-project changes +ENV CODECRAFTERS_DEPENDENCY_FILE_PATHS="dune,dune-project" + +# Change to root user. All other images seem to use root, so let's do the same here +# hadolint ignore=DL3002 +USER root + +# Install dune +RUN opam update && opam install dune.3.16.0 --yes + +# Dune path is /home/opam/.opam/5.2/bin/dune +ENV PATH="${OPAMROOT}/5.2/bin:${PATH}" + +WORKDIR /app + +# .git & README.md are unique per-repository. We ignore them on first copy to prevent cache misses +COPY --exclude=.git --exclude=README.md . /app + +# Cache dependencies +RUN opam install . --yes + +# This runs dune build +RUN .codecrafters/compile.sh + +# Once the heavy steps are done, we can copy all files back +COPY . /app \ No newline at end of file diff --git a/solutions/ocaml/01-jm1/code/.codecrafters/compile.sh b/solutions/ocaml/01-jm1/code/.codecrafters/compile.sh new file mode 100755 index 00000000..297f95d1 --- /dev/null +++ b/solutions/ocaml/01-jm1/code/.codecrafters/compile.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script is used to compile your program on CodeCrafters +# +# This runs before .codecrafters/run.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +dune build --build-dir /tmp/codecrafters-build-redis-ocaml diff --git a/solutions/ocaml/01-jm1/code/.codecrafters/run.sh b/solutions/ocaml/01-jm1/code/.codecrafters/run.sh new file mode 100755 index 00000000..9951c7c0 --- /dev/null +++ b/solutions/ocaml/01-jm1/code/.codecrafters/run.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script is used to run your program on CodeCrafters +# +# This runs after .codecrafters/compile.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +exec /tmp/codecrafters-build-redis-ocaml/default/main.exe "$@" diff --git a/solutions/ocaml/01-jm1/code/.gitattributes b/solutions/ocaml/01-jm1/code/.gitattributes new file mode 100644 index 00000000..176a458f --- /dev/null +++ b/solutions/ocaml/01-jm1/code/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/solutions/ocaml/01-jm1/code/.ocamlformat b/solutions/ocaml/01-jm1/code/.ocamlformat new file mode 100644 index 00000000..a499fbc0 --- /dev/null +++ b/solutions/ocaml/01-jm1/code/.ocamlformat @@ -0,0 +1 @@ +profile = default \ No newline at end of file diff --git a/solutions/ocaml/01-jm1/code/README.md b/solutions/ocaml/01-jm1/code/README.md new file mode 100644 index 00000000..fc59280f --- /dev/null +++ b/solutions/ocaml/01-jm1/code/README.md @@ -0,0 +1,34 @@ +![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/redis.png) + +This is a starting point for OCaml solutions to the +["Build Your Own Redis" Challenge](https://codecrafters.io/challenges/redis). + +In this challenge, you'll build a toy Redis clone that's capable of handling +basic commands like `PING`, `SET` and `GET`. Along the way we'll learn about +event loops, the Redis protocol and more. + +**Note**: If you're viewing this repo on GitHub, head over to +[codecrafters.io](https://codecrafters.io) to try the challenge. + +# Passing the first stage + +The entry point for your Redis implementation is in `src/main.ml`. Study and +uncomment the relevant code, and push your changes to pass the first stage: + +```sh +git add . +git commit -m "pass 1st stage" # any msg +git push origin master +``` + +That's all! + +# Stage 2 & beyond + +Note: This section is for stages 2 and beyond. + +1. Ensure you have `dune` installed locally +1. Run `./your_program.sh` to run your Redis server, which is implemented in + `src/main.ml`. +1. Commit your changes and run `git push origin master` to submit your solution + to CodeCrafters. Test output will be streamed to your terminal. diff --git a/solutions/ocaml/01-jm1/code/codecrafters.yml b/solutions/ocaml/01-jm1/code/codecrafters.yml new file mode 100644 index 00000000..d6ff6a7a --- /dev/null +++ b/solutions/ocaml/01-jm1/code/codecrafters.yml @@ -0,0 +1,11 @@ +# Set this to true if you want debug logs. +# +# These can be VERY verbose, so we suggest turning them off +# unless you really need them. +debug: false + +# Use this to change the OCaml version used to run your code +# on Codecrafters. +# +# Available versions: ocaml-5.2.0 +language_pack: ocaml-5.2.0 diff --git a/solutions/ocaml/01-jm1/code/codecrafters_redis.opam b/solutions/ocaml/01-jm1/code/codecrafters_redis.opam new file mode 100644 index 00000000..6240bb18 --- /dev/null +++ b/solutions/ocaml/01-jm1/code/codecrafters_redis.opam @@ -0,0 +1,27 @@ +# This file is generated by dune, edit dune-project instead +opam-version: "2.0" +version: "0.1" +synopsis: "Starter code for the Build your own Redis challenge" +maintainer: ["CodeCrafters "] +authors: ["CodeCrafters "] +license: "MIT" +homepage: "https://codecrafters.io" +bug-reports: "https://github.com/codecrafters-io/build-your-own-redis/issues" +depends: [ + "dune" {>= "3.16"} + "odoc" {with-doc} +] +build: [ + ["dune" "subst"] {dev} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] +] diff --git a/solutions/ocaml/01-jm1/code/dune b/solutions/ocaml/01-jm1/code/dune new file mode 100644 index 00000000..3e3209d2 --- /dev/null +++ b/solutions/ocaml/01-jm1/code/dune @@ -0,0 +1,5 @@ +(include_subdirs unqualified) + +(executable + (name main) + (libraries unix)) diff --git a/solutions/ocaml/01-jm1/code/dune-project b/solutions/ocaml/01-jm1/code/dune-project new file mode 100644 index 00000000..4394d358 --- /dev/null +++ b/solutions/ocaml/01-jm1/code/dune-project @@ -0,0 +1,17 @@ +(lang dune 3.16) + +(name codecrafters_redis) + +(generate_opam_files true) + +(package + (name codecrafters_redis) + (maintainers "CodeCrafters ") + (authors "CodeCrafters ") + (synopsis "Starter code for the Build your own Redis challenge") + (homepage "https://codecrafters.io") + (bug_reports + "https://github.com/codecrafters-io/build-your-own-redis/issues") + (license "MIT") + (allow_empty true) + (version 0.1)) diff --git a/solutions/ocaml/01-jm1/code/src/main.ml b/solutions/ocaml/01-jm1/code/src/main.ml new file mode 100644 index 00000000..baedeca8 --- /dev/null +++ b/solutions/ocaml/01-jm1/code/src/main.ml @@ -0,0 +1,12 @@ +open Unix + +let () = + (* Create a TCP server socket *) + let server_socket = socket PF_INET SOCK_STREAM 0 in + setsockopt server_socket SO_REUSEADDR true; + bind server_socket (ADDR_INET (inet_addr_of_string "127.0.0.1", 6379)); + listen server_socket 1; + + let (client_socket, _) = accept server_socket in + close client_socket; + close server_socket diff --git a/solutions/ocaml/01-jm1/code/your_program.sh b/solutions/ocaml/01-jm1/code/your_program.sh new file mode 100755 index 00000000..6c4a17fa --- /dev/null +++ b/solutions/ocaml/01-jm1/code/your_program.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# +# Use this script to run your program LOCALLY. +# +# Note: Changing this script WILL NOT affect how CodeCrafters runs your program. +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit early if any commands fail + +# Copied from .codecrafters/compile.sh +# +# - Edit this to change how your program compiles locally +# - Edit .codecrafters/compile.sh to change how your program compiles remotely +( + cd "$(dirname "$0")" # Ensure compile steps are run within the repository directory + dune build --build-dir /tmp/codecrafters-build-redis-ocaml +) + +# Copied from .codecrafters/run.sh +# +# - Edit this to change how your program runs locally +# - Edit .codecrafters/run.sh to change how your program runs remotely +exec /tmp/codecrafters-build-redis-ocaml/default/main.exe "$@" diff --git a/solutions/ocaml/01-jm1/diff/src/main.ml.diff b/solutions/ocaml/01-jm1/diff/src/main.ml.diff new file mode 100644 index 00000000..33d4c0cb --- /dev/null +++ b/solutions/ocaml/01-jm1/diff/src/main.ml.diff @@ -0,0 +1,20 @@ +@@ -1,16 +1,12 @@ + open Unix + + let () = +- (* You can use print statements as follows for debugging, they'll be visible when running tests. *) +- Printf.eprintf "Logs from your program will appear here!\n"; +- + (* Create a TCP server socket *) + let server_socket = socket PF_INET SOCK_STREAM 0 in + setsockopt server_socket SO_REUSEADDR true; + bind server_socket (ADDR_INET (inet_addr_of_string "127.0.0.1", 6379)); + listen server_socket 1; + +- (* Uncomment this block to pass the first stage *) +- (* let (client_socket, _) = accept server_socket in *) +- (* close client_socket; *) +- (* close server_socket *) ++ let (client_socket, _) = accept server_socket in ++ close client_socket; ++ close server_socket diff --git a/solutions/ocaml/01-jm1/explanation.md b/solutions/ocaml/01-jm1/explanation.md new file mode 100644 index 00000000..7265c749 --- /dev/null +++ b/solutions/ocaml/01-jm1/explanation.md @@ -0,0 +1,18 @@ +The entry point for your Redis implementation is in `src/main.ml`. + +Study and uncomment the relevant code: + +```ocaml +(* Uncomment this block to pass the first stage *) +let (client_socket, _) = accept server_socket in +close client_socket; +close server_socket +``` + +Push your changes to pass the first stage: + +``` +git add . +git commit -m "pass 1st stage" # any msg +git push origin master +``` diff --git a/starter_templates/ocaml/code/.codecrafters/compile.sh b/starter_templates/ocaml/code/.codecrafters/compile.sh new file mode 100755 index 00000000..297f95d1 --- /dev/null +++ b/starter_templates/ocaml/code/.codecrafters/compile.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script is used to compile your program on CodeCrafters +# +# This runs before .codecrafters/run.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +dune build --build-dir /tmp/codecrafters-build-redis-ocaml diff --git a/starter_templates/ocaml/code/.codecrafters/run.sh b/starter_templates/ocaml/code/.codecrafters/run.sh new file mode 100755 index 00000000..9951c7c0 --- /dev/null +++ b/starter_templates/ocaml/code/.codecrafters/run.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script is used to run your program on CodeCrafters +# +# This runs after .codecrafters/compile.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +exec /tmp/codecrafters-build-redis-ocaml/default/main.exe "$@" diff --git a/starter_templates/ocaml/code/.ocamlformat b/starter_templates/ocaml/code/.ocamlformat new file mode 100644 index 00000000..a499fbc0 --- /dev/null +++ b/starter_templates/ocaml/code/.ocamlformat @@ -0,0 +1 @@ +profile = default \ No newline at end of file diff --git a/starter_templates/ocaml/code/codecrafters_redis.opam b/starter_templates/ocaml/code/codecrafters_redis.opam new file mode 100644 index 00000000..6240bb18 --- /dev/null +++ b/starter_templates/ocaml/code/codecrafters_redis.opam @@ -0,0 +1,27 @@ +# This file is generated by dune, edit dune-project instead +opam-version: "2.0" +version: "0.1" +synopsis: "Starter code for the Build your own Redis challenge" +maintainer: ["CodeCrafters "] +authors: ["CodeCrafters "] +license: "MIT" +homepage: "https://codecrafters.io" +bug-reports: "https://github.com/codecrafters-io/build-your-own-redis/issues" +depends: [ + "dune" {>= "3.16"} + "odoc" {with-doc} +] +build: [ + ["dune" "subst"] {dev} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] +] diff --git a/starter_templates/ocaml/code/dune b/starter_templates/ocaml/code/dune new file mode 100644 index 00000000..3e3209d2 --- /dev/null +++ b/starter_templates/ocaml/code/dune @@ -0,0 +1,5 @@ +(include_subdirs unqualified) + +(executable + (name main) + (libraries unix)) diff --git a/starter_templates/ocaml/code/dune-project b/starter_templates/ocaml/code/dune-project new file mode 100644 index 00000000..4394d358 --- /dev/null +++ b/starter_templates/ocaml/code/dune-project @@ -0,0 +1,17 @@ +(lang dune 3.16) + +(name codecrafters_redis) + +(generate_opam_files true) + +(package + (name codecrafters_redis) + (maintainers "CodeCrafters ") + (authors "CodeCrafters ") + (synopsis "Starter code for the Build your own Redis challenge") + (homepage "https://codecrafters.io") + (bug_reports + "https://github.com/codecrafters-io/build-your-own-redis/issues") + (license "MIT") + (allow_empty true) + (version 0.1)) diff --git a/starter_templates/ocaml/code/src/main.ml b/starter_templates/ocaml/code/src/main.ml new file mode 100644 index 00000000..f1fe0aa5 --- /dev/null +++ b/starter_templates/ocaml/code/src/main.ml @@ -0,0 +1,16 @@ +open Unix + +let () = + (* You can use print statements as follows for debugging, they'll be visible when running tests. *) + Printf.eprintf "Logs from your program will appear here!\n"; + + (* Create a TCP server socket *) + let server_socket = socket PF_INET SOCK_STREAM 0 in + setsockopt server_socket SO_REUSEADDR true; + bind server_socket (ADDR_INET (inet_addr_of_string "127.0.0.1", 6379)); + listen server_socket 1; + + (* Uncomment this block to pass the first stage *) + (* let (client_socket, _) = accept server_socket in *) + (* close client_socket; *) + (* close server_socket *) diff --git a/starter_templates/ocaml/config.yml b/starter_templates/ocaml/config.yml new file mode 100644 index 00000000..edac0d49 --- /dev/null +++ b/starter_templates/ocaml/config.yml @@ -0,0 +1,3 @@ +attributes: + required_executable: "dune" + user_editable_file: "src/main.ml"