diff --git a/compiled_starters/clojure/.codecrafters/compile.sh b/compiled_starters/clojure/.codecrafters/compile.sh new file mode 100755 index 0000000..e5c4b41 --- /dev/null +++ b/compiled_starters/clojure/.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 + +clj -T:build uber \ No newline at end of file diff --git a/compiled_starters/clojure/.codecrafters/run.sh b/compiled_starters/clojure/.codecrafters/run.sh new file mode 100755 index 0000000..08b2bef --- /dev/null +++ b/compiled_starters/clojure/.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 java -jar /tmp/codecrafters-build-http-server-clojure/codecrafters-http-server-clojure-standalone.jar "$@" \ No newline at end of file diff --git a/compiled_starters/clojure/.gitattributes b/compiled_starters/clojure/.gitattributes new file mode 100644 index 0000000..176a458 --- /dev/null +++ b/compiled_starters/clojure/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/compiled_starters/clojure/.gitignore b/compiled_starters/clojure/.gitignore new file mode 100644 index 0000000..919e506 --- /dev/null +++ b/compiled_starters/clojure/.gitignore @@ -0,0 +1,10 @@ +*.jar +target/ +.idea/ +.clj-kondo/ +.lsp/ +.nrepl-port +*.class +/lib/ +/classes/ +.cpcache/ \ No newline at end of file diff --git a/compiled_starters/clojure/README.md b/compiled_starters/clojure/README.md new file mode 100644 index 0000000..1eb6452 --- /dev/null +++ b/compiled_starters/clojure/README.md @@ -0,0 +1,37 @@ +![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/http-server.png) + +This is a starting point for Clojure solutions to the +["Build Your Own HTTP server" Challenge](https://app.codecrafters.io/courses/http-server/overview). + +[HTTP](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol) is the +protocol that powers the web. In this challenge, you'll build a HTTP/1.1 server +that is capable of serving multiple clients. + +Along the way you'll learn about TCP servers, +[HTTP request syntax](https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html), +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 HTTP server implementation is in `src/main.clj`. Study +and uncomment the relevant code, and push your changes to pass the first stage: + +```sh +git commit -am "pass 1st stage" # any msg +git push origin master +``` + +Time to move on to the next stage! + +# Stage 2 & beyond + +Note: This section is for stages 2 and beyond. + +1. Ensure you have `clj (1.12.0)` installed locally +1. Run `./your_program.sh` to run your program, which is implemented in + `src/main.clj`. +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/clojure/build.clj b/compiled_starters/clojure/build.clj new file mode 100644 index 0000000..001968e --- /dev/null +++ b/compiled_starters/clojure/build.clj @@ -0,0 +1,58 @@ +(ns build + (:require [clojure.tools.build.api :as b] + [clojure.edn :as edn])) + +(def project (-> (edn/read-string (slurp "deps.edn")) + :aliases :neil :project)) +(def lib (or (:name project) 'my/lib1)) + +(def version (or (:version project) + "0.0.1")) +(def class-dir "target/classes") +(def basis (b/create-basis {:project "deps.edn"})) +(def uber-file "/tmp/codecrafters-build-http-server-clojure/codecrafters-http-server-clojure-standalone.jar") +(def jar-file "/tmp/codecrafters-build-http-server-clojure/codecrafters-http-server-clojure.jar") + +(defn clean [_] + (b/delete {:path "target"})) + +(defn jar [_] + (b/write-pom {:class-dir class-dir + :lib lib + :version version + :basis basis + :src-dirs ["src"]}) + (b/copy-dir {:src-dirs ["src" "resources"] + :target-dir class-dir}) + (b/jar {:class-dir class-dir + :jar-file jar-file})) + +(defn install [_] + (jar {}) + (b/install {:basis basis + :lib lib + :version version + :jar-file jar-file + :class-dir class-dir})) + +(defn uber [_] + (clean nil) + (b/copy-dir {:src-dirs ["src" "resources"] + :target-dir class-dir}) + (b/compile-clj {:basis basis + :src-dirs ["src"] + :class-dir class-dir}) + (b/uber {:class-dir class-dir + :uber-file uber-file + :basis basis + :main 'main})) + +(defn deploy [opts] + (jar opts) + ((requiring-resolve 'deps-deploy.deps-deploy/deploy) + (merge {:installer :remote + :artifact jar-file + :pom-file (b/pom-path {:lib lib :class-dir class-dir})} + opts)) + opts) + diff --git a/compiled_starters/clojure/codecrafters.yml b/compiled_starters/clojure/codecrafters.yml new file mode 100644 index 0000000..6960f61 --- /dev/null +++ b/compiled_starters/clojure/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 Clojure version used to run your code +# on Codecrafters. +# +# Available versions: clojure-1.12 +language_pack: clojure-1.12 diff --git a/compiled_starters/clojure/deps.edn b/compiled_starters/clojure/deps.edn new file mode 100644 index 0000000..a992cc7 --- /dev/null +++ b/compiled_starters/clojure/deps.edn @@ -0,0 +1,6 @@ +{:paths ["src"] + :deps {} + :aliases {:build {:deps {io.github.clojure/tools.build {:git/tag "v0.10.7" + :git/sha "573711e"} + slipset/deps-deploy {:mvn/version "0.2.2"}} + :ns-default build}}} diff --git a/compiled_starters/clojure/src/main.clj b/compiled_starters/clojure/src/main.clj new file mode 100644 index 0000000..f6a7055 --- /dev/null +++ b/compiled_starters/clojure/src/main.clj @@ -0,0 +1,16 @@ +(ns main + (:gen-class)) + +(defn -main [& args] +;; You can use print statements as follows for debugging, they'll be visible when running tests. + (println "Logs from your program will appear here!") +;; Uncomment this block to pass the first stage +;; (try +;; (with-open [server-socket (java.net.ServerSocket. 4221)] +;; (doto server-socket +;; (.setReuseAddress true) +;; (.accept)) +;; (println "accepted new connection")) +;; (catch java.io.IOException e +;; (println (str "IOException: " (.getMessage e))))) +) \ No newline at end of file diff --git a/compiled_starters/clojure/your_program.sh b/compiled_starters/clojure/your_program.sh new file mode 100755 index 0000000..77e6366 --- /dev/null +++ b/compiled_starters/clojure/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 + clj -T:build uber +) + +# 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 java -jar /tmp/codecrafters-build-http-server-clojure/codecrafters-http-server-clojure-standalone.jar "$@" diff --git a/dockerfiles/clojure-1.12.Dockerfile b/dockerfiles/clojure-1.12.Dockerfile new file mode 100644 index 0000000..b2db050 --- /dev/null +++ b/dockerfiles/clojure-1.12.Dockerfile @@ -0,0 +1,13 @@ +# syntax=docker/dockerfile:1.7-labs +FROM clojure:tools-deps-1.12.0.1501-bookworm + +ENV CODECRAFTERS_DEPENDENCY_FILE_PATHS="deps.edn" + +WORKDIR /app +# COPY deps.edn ./ + +# .git & README.md are unique per-repository. We ignore them on first copy to prevent cache misses +COPY --exclude=.git --exclude=README.md . /app + +# Install language-specific dependencies +RUN .codecrafters/compile.sh \ No newline at end of file diff --git a/solutions/clojure/01-at4/code/.codecrafters/compile.sh b/solutions/clojure/01-at4/code/.codecrafters/compile.sh new file mode 100755 index 0000000..e5c4b41 --- /dev/null +++ b/solutions/clojure/01-at4/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 + +clj -T:build uber \ No newline at end of file diff --git a/solutions/clojure/01-at4/code/.codecrafters/run.sh b/solutions/clojure/01-at4/code/.codecrafters/run.sh new file mode 100755 index 0000000..08b2bef --- /dev/null +++ b/solutions/clojure/01-at4/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 java -jar /tmp/codecrafters-build-http-server-clojure/codecrafters-http-server-clojure-standalone.jar "$@" \ No newline at end of file diff --git a/solutions/clojure/01-at4/code/.gitattributes b/solutions/clojure/01-at4/code/.gitattributes new file mode 100644 index 0000000..176a458 --- /dev/null +++ b/solutions/clojure/01-at4/code/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/solutions/clojure/01-at4/code/.gitignore b/solutions/clojure/01-at4/code/.gitignore new file mode 100644 index 0000000..919e506 --- /dev/null +++ b/solutions/clojure/01-at4/code/.gitignore @@ -0,0 +1,10 @@ +*.jar +target/ +.idea/ +.clj-kondo/ +.lsp/ +.nrepl-port +*.class +/lib/ +/classes/ +.cpcache/ \ No newline at end of file diff --git a/solutions/clojure/01-at4/code/README.md b/solutions/clojure/01-at4/code/README.md new file mode 100644 index 0000000..1eb6452 --- /dev/null +++ b/solutions/clojure/01-at4/code/README.md @@ -0,0 +1,37 @@ +![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/http-server.png) + +This is a starting point for Clojure solutions to the +["Build Your Own HTTP server" Challenge](https://app.codecrafters.io/courses/http-server/overview). + +[HTTP](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol) is the +protocol that powers the web. In this challenge, you'll build a HTTP/1.1 server +that is capable of serving multiple clients. + +Along the way you'll learn about TCP servers, +[HTTP request syntax](https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html), +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 HTTP server implementation is in `src/main.clj`. Study +and uncomment the relevant code, and push your changes to pass the first stage: + +```sh +git commit -am "pass 1st stage" # any msg +git push origin master +``` + +Time to move on to the next stage! + +# Stage 2 & beyond + +Note: This section is for stages 2 and beyond. + +1. Ensure you have `clj (1.12.0)` installed locally +1. Run `./your_program.sh` to run your program, which is implemented in + `src/main.clj`. +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/clojure/01-at4/code/build.clj b/solutions/clojure/01-at4/code/build.clj new file mode 100644 index 0000000..001968e --- /dev/null +++ b/solutions/clojure/01-at4/code/build.clj @@ -0,0 +1,58 @@ +(ns build + (:require [clojure.tools.build.api :as b] + [clojure.edn :as edn])) + +(def project (-> (edn/read-string (slurp "deps.edn")) + :aliases :neil :project)) +(def lib (or (:name project) 'my/lib1)) + +(def version (or (:version project) + "0.0.1")) +(def class-dir "target/classes") +(def basis (b/create-basis {:project "deps.edn"})) +(def uber-file "/tmp/codecrafters-build-http-server-clojure/codecrafters-http-server-clojure-standalone.jar") +(def jar-file "/tmp/codecrafters-build-http-server-clojure/codecrafters-http-server-clojure.jar") + +(defn clean [_] + (b/delete {:path "target"})) + +(defn jar [_] + (b/write-pom {:class-dir class-dir + :lib lib + :version version + :basis basis + :src-dirs ["src"]}) + (b/copy-dir {:src-dirs ["src" "resources"] + :target-dir class-dir}) + (b/jar {:class-dir class-dir + :jar-file jar-file})) + +(defn install [_] + (jar {}) + (b/install {:basis basis + :lib lib + :version version + :jar-file jar-file + :class-dir class-dir})) + +(defn uber [_] + (clean nil) + (b/copy-dir {:src-dirs ["src" "resources"] + :target-dir class-dir}) + (b/compile-clj {:basis basis + :src-dirs ["src"] + :class-dir class-dir}) + (b/uber {:class-dir class-dir + :uber-file uber-file + :basis basis + :main 'main})) + +(defn deploy [opts] + (jar opts) + ((requiring-resolve 'deps-deploy.deps-deploy/deploy) + (merge {:installer :remote + :artifact jar-file + :pom-file (b/pom-path {:lib lib :class-dir class-dir})} + opts)) + opts) + diff --git a/solutions/clojure/01-at4/code/codecrafters.yml b/solutions/clojure/01-at4/code/codecrafters.yml new file mode 100644 index 0000000..6960f61 --- /dev/null +++ b/solutions/clojure/01-at4/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 Clojure version used to run your code +# on Codecrafters. +# +# Available versions: clojure-1.12 +language_pack: clojure-1.12 diff --git a/solutions/clojure/01-at4/code/deps.edn b/solutions/clojure/01-at4/code/deps.edn new file mode 100644 index 0000000..a992cc7 --- /dev/null +++ b/solutions/clojure/01-at4/code/deps.edn @@ -0,0 +1,6 @@ +{:paths ["src"] + :deps {} + :aliases {:build {:deps {io.github.clojure/tools.build {:git/tag "v0.10.7" + :git/sha "573711e"} + slipset/deps-deploy {:mvn/version "0.2.2"}} + :ns-default build}}} diff --git a/solutions/clojure/01-at4/code/src/main.clj b/solutions/clojure/01-at4/code/src/main.clj new file mode 100644 index 0000000..f28ae5a --- /dev/null +++ b/solutions/clojure/01-at4/code/src/main.clj @@ -0,0 +1,13 @@ +(ns main + (:gen-class)) + +(defn -main [& args] +(try + (with-open [server-socket (java.net.ServerSocket. 4221)] + (doto server-socket + (.setReuseAddress true) + (.accept)) + (println "accepted new connection")) + (catch java.io.IOException e + (println (str "IOException: " (.getMessage e))))) +) \ No newline at end of file diff --git a/solutions/clojure/01-at4/code/your_program.sh b/solutions/clojure/01-at4/code/your_program.sh new file mode 100755 index 0000000..77e6366 --- /dev/null +++ b/solutions/clojure/01-at4/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 + clj -T:build uber +) + +# 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 java -jar /tmp/codecrafters-build-http-server-clojure/codecrafters-http-server-clojure-standalone.jar "$@" diff --git a/solutions/clojure/01-at4/diff/src/main.clj.diff b/solutions/clojure/01-at4/diff/src/main.clj.diff new file mode 100644 index 0000000..8528b49 --- /dev/null +++ b/solutions/clojure/01-at4/diff/src/main.clj.diff @@ -0,0 +1,26 @@ +@@ -1,16 +1,13 @@ + (ns main + (:gen-class)) + + (defn -main [& args] +-;; You can use print statements as follows for debugging, they'll be visible when running tests. +- (println "Logs from your program will appear here!") +-;; Uncomment this block to pass the first stage +-;; (try +-;; (with-open [server-socket (java.net.ServerSocket. 4221)] +-;; (doto server-socket +-;; (.setReuseAddress true) +-;; (.accept)) +-;; (println "accepted new connection")) +-;; (catch java.io.IOException e +-;; (println (str "IOException: " (.getMessage e))))) ++(try ++ (with-open [server-socket (java.net.ServerSocket. 4221)] ++ (doto server-socket ++ (.setReuseAddress true) ++ (.accept)) ++ (println "accepted new connection")) ++ (catch java.io.IOException e ++ (println (str "IOException: " (.getMessage e))))) + ) +\ No newline at end of file diff --git a/solutions/clojure/01-at4/explanation.md b/solutions/clojure/01-at4/explanation.md new file mode 100644 index 0000000..ffd5cd5 --- /dev/null +++ b/solutions/clojure/01-at4/explanation.md @@ -0,0 +1,23 @@ +The entry point for your HTTP server implementation is in `src/main.clj`. + +Study and uncomment the relevant code: + +```clojure +;; Uncomment this block to pass the first stage +(try + (with-open [server-socket (java.net.ServerSocket. 4221)] + (doto server-socket + (.setReuseAddress true) + (.accept)) + (println "accepted new connection")) + (catch java.io.IOException e + (println (str "IOException: " (.getMessage e))))) +``` + +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/clojure/code/.codecrafters/compile.sh b/starter_templates/clojure/code/.codecrafters/compile.sh new file mode 100755 index 0000000..e5c4b41 --- /dev/null +++ b/starter_templates/clojure/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 + +clj -T:build uber \ No newline at end of file diff --git a/starter_templates/clojure/code/.codecrafters/run.sh b/starter_templates/clojure/code/.codecrafters/run.sh new file mode 100755 index 0000000..08b2bef --- /dev/null +++ b/starter_templates/clojure/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 java -jar /tmp/codecrafters-build-http-server-clojure/codecrafters-http-server-clojure-standalone.jar "$@" \ No newline at end of file diff --git a/starter_templates/clojure/code/.gitignore b/starter_templates/clojure/code/.gitignore new file mode 100644 index 0000000..919e506 --- /dev/null +++ b/starter_templates/clojure/code/.gitignore @@ -0,0 +1,10 @@ +*.jar +target/ +.idea/ +.clj-kondo/ +.lsp/ +.nrepl-port +*.class +/lib/ +/classes/ +.cpcache/ \ No newline at end of file diff --git a/starter_templates/clojure/code/build.clj b/starter_templates/clojure/code/build.clj new file mode 100644 index 0000000..001968e --- /dev/null +++ b/starter_templates/clojure/code/build.clj @@ -0,0 +1,58 @@ +(ns build + (:require [clojure.tools.build.api :as b] + [clojure.edn :as edn])) + +(def project (-> (edn/read-string (slurp "deps.edn")) + :aliases :neil :project)) +(def lib (or (:name project) 'my/lib1)) + +(def version (or (:version project) + "0.0.1")) +(def class-dir "target/classes") +(def basis (b/create-basis {:project "deps.edn"})) +(def uber-file "/tmp/codecrafters-build-http-server-clojure/codecrafters-http-server-clojure-standalone.jar") +(def jar-file "/tmp/codecrafters-build-http-server-clojure/codecrafters-http-server-clojure.jar") + +(defn clean [_] + (b/delete {:path "target"})) + +(defn jar [_] + (b/write-pom {:class-dir class-dir + :lib lib + :version version + :basis basis + :src-dirs ["src"]}) + (b/copy-dir {:src-dirs ["src" "resources"] + :target-dir class-dir}) + (b/jar {:class-dir class-dir + :jar-file jar-file})) + +(defn install [_] + (jar {}) + (b/install {:basis basis + :lib lib + :version version + :jar-file jar-file + :class-dir class-dir})) + +(defn uber [_] + (clean nil) + (b/copy-dir {:src-dirs ["src" "resources"] + :target-dir class-dir}) + (b/compile-clj {:basis basis + :src-dirs ["src"] + :class-dir class-dir}) + (b/uber {:class-dir class-dir + :uber-file uber-file + :basis basis + :main 'main})) + +(defn deploy [opts] + (jar opts) + ((requiring-resolve 'deps-deploy.deps-deploy/deploy) + (merge {:installer :remote + :artifact jar-file + :pom-file (b/pom-path {:lib lib :class-dir class-dir})} + opts)) + opts) + diff --git a/starter_templates/clojure/code/deps.edn b/starter_templates/clojure/code/deps.edn new file mode 100644 index 0000000..a992cc7 --- /dev/null +++ b/starter_templates/clojure/code/deps.edn @@ -0,0 +1,6 @@ +{:paths ["src"] + :deps {} + :aliases {:build {:deps {io.github.clojure/tools.build {:git/tag "v0.10.7" + :git/sha "573711e"} + slipset/deps-deploy {:mvn/version "0.2.2"}} + :ns-default build}}} diff --git a/starter_templates/clojure/code/src/main.clj b/starter_templates/clojure/code/src/main.clj new file mode 100644 index 0000000..f6a7055 --- /dev/null +++ b/starter_templates/clojure/code/src/main.clj @@ -0,0 +1,16 @@ +(ns main + (:gen-class)) + +(defn -main [& args] +;; You can use print statements as follows for debugging, they'll be visible when running tests. + (println "Logs from your program will appear here!") +;; Uncomment this block to pass the first stage +;; (try +;; (with-open [server-socket (java.net.ServerSocket. 4221)] +;; (doto server-socket +;; (.setReuseAddress true) +;; (.accept)) +;; (println "accepted new connection")) +;; (catch java.io.IOException e +;; (println (str "IOException: " (.getMessage e))))) +) \ No newline at end of file diff --git a/starter_templates/clojure/config.yml b/starter_templates/clojure/config.yml new file mode 100644 index 0000000..58bf7ac --- /dev/null +++ b/starter_templates/clojure/config.yml @@ -0,0 +1,3 @@ +attributes: + required_executable: clj (1.12.0) + user_editable_file: src/main.clj