From 50e0bd6c08e6131ff4e811c253b3fb37a1c6803f Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Mon, 30 May 2022 15:24:23 -0600 Subject: [PATCH 01/26] fixture.ml: more tests --- workspace/fixture.ml | 46 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/workspace/fixture.ml b/workspace/fixture.ml index 2f0bf63..184727d 100644 --- a/workspace/fixture.ml +++ b/workspace/fixture.ml @@ -1,8 +1,48 @@ (* TODO Avoid concatenating in the next version *) -let add x y = x + y;; +let is_even n = n mod 2 = 0 module Tests = struct open OUnit - let test1 test_ctxt = assert_equal 2 (add 1 1);; - let suite = ["1+1 is 2" >:: test1];; + let suite = [ + "Top level test case" >:: (fun _ -> assert_equal false (is_even 1024)); + "Test Odd" >::: + [ + "Should return false for 1" >:: (fun _ -> assert_equal false (is_even 1)); + "Should return false for 7" >:: (fun _ -> assert_equal false (is_even 7)) + ]; + "Test even" >::: + [ + "Should return true for 100" >:: (fun _ -> assert_equal true (is_even 100)); + "Should return true for 42" >:: (fun _ -> assert_equal true (is_even 42)) + ]; + "Test edge cases" >::: + [ + "Test zero" >::: + [ + "Should return true for 0" >:: (fun _ -> assert_equal true (is_even 0)) + ]; + "Test -1" >::: + [ + "Should return false for -1" >:: (fun _ -> assert_equal false (is_even (-1))) + ] + ]; + "Unlabeled tests" >::: + [ + TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100"); + TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100"); + TestList [ + TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100"); + TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100"); + ] + + ]; + "Nested labels" >::: [ + "Outer label" >: ("Inner label" >: ("Tests with nested labels" >::: [ + TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100" ~printer: string_of_bool); + TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100" ~printer: string_of_bool); + + ])) + ] + ] + ;; end From fe490bb7cc3f7cb26d0f76508a76a3e98456ffdd Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Sun, 12 Jun 2022 21:32:45 -0600 Subject: [PATCH 02/26] Dockerfile for OCaml 4.14 --- Dockerfile | 42 ++++++++++++++++++------------------------ workspace/_tags | 4 ++-- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/Dockerfile b/Dockerfile index c49803d..009d973 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,9 @@ -FROM buildpack-deps:bionic +FROM ubuntu:22.04 RUN set -ex; \ useradd --create-home codewarrior; \ -# TODO Remove symlink in the next version - ln -s /home/codewarrior /workspace; + mkdir -p /workspace; \ + chown -R codewarrior:codewarrior /workspace; ENV OPAMROOT=/opt/opam \ OPAMCOLOR=never @@ -14,35 +14,29 @@ RUN set -ex; \ apt-get update; \ apt-get install -y --no-install-recommends \ software-properties-common \ - m4 \ - rsync \ - aspcud \ - ; \ -# Needed for opam 2.0 - add-apt-repository -y ppa:avsm/ppa; \ - apt-get update; \ - apt-get install -y --no-install-recommends \ + libgmp-dev \ opam \ - ; \ - rm -rf /var/lib/apt/lists/*; + ; USER codewarrior ENV USER=codewarrior \ HOME=/home/codewarrior -# --disable-sandboxing is needed to do this in a container witout `--privileged` -RUN opam init -y --compiler=4.07.1 --disable-sandboxing - -ENV OPAM_SWITCH_PREFIX=/opt/opam/4.07.1 \ - CAML_LD_LIBRARY_PATH=/opt/opam/4.07.1/lib/stublibs \ - OCAML_TOPLEVEL_PATH=/opt/opam/4.07.1/lib/toplevel \ - PATH=/opt/opam/4.07.1/bin:$PATH +RUN opam init -y --shell-setup --compiler=4.14.0 --disable-sandboxing RUN opam install -y \ - 'ounit=2.0.8' \ - 'batteries=2.9.0' \ - 'core=v0.11.3' \ + 'ounit2=2.2.6' \ + 'ocamlfind=1.9.3' \ + 'ocamlbuild=0.14.1' \ + 'zarith=1.12' \ + 'batteries=3.5.1' \ + 'core=v0.15.0' \ ; +ENV OPAM_SWITCH_PREFIX=$OPAMROOT/4.14.0 \ + CAML_LD_LIBRARY_PATH=$OPAMROOT/4.14.0/lib/stublibs:$OPAMROOT/4.14.0/lib/ocaml/stublibs:$OPAMROOT/4.14.0/lib/ocaml \ + OCAML_TOPLEVEL_PATH=$OPAMROOT/4.14.0/lib/toplevel \ + PATH=$OPAMROOT/4.14.0/bin:$PATH + COPY workspace/test.ml /workspace/test.ml -COPY workspace/_tags /workspace/_tags +COPY workspace/_tags /workspace/_tags \ No newline at end of file diff --git a/workspace/_tags b/workspace/_tags index c459396..b81ef8a 100644 --- a/workspace/_tags +++ b/workspace/_tags @@ -1,2 +1,2 @@ - : package(oUnit), use_str - or : package(oUnit), package(batteries), package(core), thread + : package(ounit2), use_str + or : package(ounit2), package(batteries), package(core), thread From f8c239d4d27ce6aa18a37be3e46c88adea0423f1 Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Mon, 3 Apr 2023 20:42:48 -0600 Subject: [PATCH 03/26] Add DockerOcamlbuild: Ubuntu 22.04 + OCaml 5.0 + ocamlbuild --- DockerOcamlbuild | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 DockerOcamlbuild diff --git a/DockerOcamlbuild b/DockerOcamlbuild new file mode 100644 index 0000000..c550131 --- /dev/null +++ b/DockerOcamlbuild @@ -0,0 +1,19 @@ +FROM ocaml/opam:ubuntu-22.04-ocaml-5.0 + +RUN set -ex; \ + eval $(opam env); \ + opam install -y \ + 'ounit2=2.2.7' \ + 'ocamlbuild=0.14.2' \ + 'batteries=3.6.0' \ +# 'core=v0.15.1' \ +# '' + ; + +USER opam +ENV USER=opam + +RUN sudo mkdir -p /workspace; \ + sudo chown opam:opam /workspace +COPY workspace/test.ml /workspace/test.ml +COPY example/ /workspace/ \ No newline at end of file From 18b7d8597b41d790e075c2bbe9ef8ae8d6491f9e Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Mon, 3 Apr 2023 21:32:50 -0600 Subject: [PATCH 04/26] Add examples --- examples/basic/preloaded.ml | 0 examples/basic/solution.ml | 1 + examples/basic/tests.ml | 44 +++++++++++++++++++++++++++++++++ examples/batteries/preloaded.ml | 0 examples/batteries/solution.ml | 6 +++++ examples/batteries/tests.ml | 9 +++++++ 6 files changed, 60 insertions(+) create mode 100644 examples/basic/preloaded.ml create mode 100644 examples/basic/solution.ml create mode 100644 examples/basic/tests.ml create mode 100644 examples/batteries/preloaded.ml create mode 100644 examples/batteries/solution.ml create mode 100644 examples/batteries/tests.ml diff --git a/examples/basic/preloaded.ml b/examples/basic/preloaded.ml new file mode 100644 index 0000000..e69de29 diff --git a/examples/basic/solution.ml b/examples/basic/solution.ml new file mode 100644 index 0000000..ea7dd3f --- /dev/null +++ b/examples/basic/solution.ml @@ -0,0 +1 @@ +let is_even n = n mod 2 = 0 \ No newline at end of file diff --git a/examples/basic/tests.ml b/examples/basic/tests.ml new file mode 100644 index 0000000..05c9e4d --- /dev/null +++ b/examples/basic/tests.ml @@ -0,0 +1,44 @@ +open Solution +open OUnit + +let suite = [ + "Top level test case" >:: (fun _ -> assert_equal false (is_even 1024)); + "Test Odd" >::: + [ + "Should return false for 1" >:: (fun _ -> assert_equal false (is_even 1)); + "Should return false for 7" >:: (fun _ -> assert_equal false (is_even 7)) + ]; + "Test even" >::: + [ + "Should return true for 100" >:: (fun _ -> assert_equal true (is_even 100)); + "Should return true for 42" >:: (fun _ -> assert_equal true (is_even 42)) + ]; + "Test edge cases" >::: + [ + "Test zero" >::: + [ + "Should return true for 0" >:: (fun _ -> assert_equal true (is_even 0)) + ]; + "Test -1" >::: + [ + "Should return false for -1" >:: (fun _ -> assert_equal false (is_even (-1))) + ] + ]; + "Unlabeled tests" >::: + [ + TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100"); + TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100"); + TestList [ + TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100"); + TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100"); + ] + + ]; + "Nested labels" >::: [ + "Outer label" >: ("Inner label" >: ("Tests with nested labels" >::: [ + TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100" ~printer: string_of_bool); + TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100" ~printer: string_of_bool); + + ])) + ] + ] diff --git a/examples/batteries/preloaded.ml b/examples/batteries/preloaded.ml new file mode 100644 index 0000000..e69de29 diff --git a/examples/batteries/solution.ml b/examples/batteries/solution.ml new file mode 100644 index 0000000..73b04e1 --- /dev/null +++ b/examples/batteries/solution.ml @@ -0,0 +1,6 @@ +open Batteries + +let sum n = + (1 -- n) + |> Enum.map (fun i -> Num.num_of_int i |> Num.int_of_num) + |> Enum.sum \ No newline at end of file diff --git a/examples/batteries/tests.ml b/examples/batteries/tests.ml new file mode 100644 index 0000000..9e21ec2 --- /dev/null +++ b/examples/batteries/tests.ml @@ -0,0 +1,9 @@ +open OUnit + +let suite = [ + "Fixed tests" >::: + [ + "Testing 1" >:: (fun _ -> assert_equal 1 (Solution.sum 1) ~printer:string_of_int); + "Testing 10" >:: (fun _ -> assert_equal 45 (Solution.sum 9) ~printer:string_of_int); + ]; + ] \ No newline at end of file From f7306b13d9b8ba60168e5192867ff3c4e13312c3 Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Mon, 3 Apr 2023 21:33:34 -0600 Subject: [PATCH 05/26] Remove fixture.ml and update test.ml and _tags --- DockerOcamlbuild | 2 +- workspace/_tags | 5 +++-- workspace/fixture.ml | 48 -------------------------------------------- workspace/test.ml | 2 +- 4 files changed, 5 insertions(+), 52 deletions(-) delete mode 100644 workspace/fixture.ml diff --git a/DockerOcamlbuild b/DockerOcamlbuild index c550131..c6b8f8c 100644 --- a/DockerOcamlbuild +++ b/DockerOcamlbuild @@ -16,4 +16,4 @@ ENV USER=opam RUN sudo mkdir -p /workspace; \ sudo chown opam:opam /workspace COPY workspace/test.ml /workspace/test.ml -COPY example/ /workspace/ \ No newline at end of file +COPY workspace/_tags /workspace/_tags \ No newline at end of file diff --git a/workspace/_tags b/workspace/_tags index b81ef8a..1ac93b4 100644 --- a/workspace/_tags +++ b/workspace/_tags @@ -1,2 +1,3 @@ - : package(ounit2), use_str - or : package(ounit2), package(batteries), package(core), thread + or or : package(ounit2) +not : package(batteries) +# not : package(batteries), package(core) \ No newline at end of file diff --git a/workspace/fixture.ml b/workspace/fixture.ml deleted file mode 100644 index 184727d..0000000 --- a/workspace/fixture.ml +++ /dev/null @@ -1,48 +0,0 @@ -(* TODO Avoid concatenating in the next version *) -let is_even n = n mod 2 = 0 - -module Tests = struct - open OUnit - let suite = [ - "Top level test case" >:: (fun _ -> assert_equal false (is_even 1024)); - "Test Odd" >::: - [ - "Should return false for 1" >:: (fun _ -> assert_equal false (is_even 1)); - "Should return false for 7" >:: (fun _ -> assert_equal false (is_even 7)) - ]; - "Test even" >::: - [ - "Should return true for 100" >:: (fun _ -> assert_equal true (is_even 100)); - "Should return true for 42" >:: (fun _ -> assert_equal true (is_even 42)) - ]; - "Test edge cases" >::: - [ - "Test zero" >::: - [ - "Should return true for 0" >:: (fun _ -> assert_equal true (is_even 0)) - ]; - "Test -1" >::: - [ - "Should return false for -1" >:: (fun _ -> assert_equal false (is_even (-1))) - ] - ]; - "Unlabeled tests" >::: - [ - TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100"); - TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100"); - TestList [ - TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100"); - TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100"); - ] - - ]; - "Nested labels" >::: [ - "Outer label" >: ("Inner label" >: ("Tests with nested labels" >::: [ - TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100" ~printer: string_of_bool); - TestCase (fun _ -> assert_equal false (is_even 100) ~msg:"Incorrect answer for n=100" ~printer: string_of_bool); - - ])) - ] - ] - ;; -end diff --git a/workspace/test.ml b/workspace/test.ml index e3dede9..6f25109 100644 --- a/workspace/test.ml +++ b/workspace/test.ml @@ -56,4 +56,4 @@ and run_test = function and run_tests tests = List.iter run_test tests (* `solution` and `fixture` are concatenated to `fixture.ml` *) -let () = run_tests Fixture.Tests.suite +let () = run_tests Tests.suite From c67b5a2f72fd98afa24cb40f7e5a156a141adb09 Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Mon, 3 Apr 2023 21:34:32 -0600 Subject: [PATCH 06/26] Add script files to build and run containers --- bin/build_ocamlbuild | 1 + bin/run_ocamlbuild | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100755 bin/build_ocamlbuild create mode 100755 bin/run_ocamlbuild diff --git a/bin/build_ocamlbuild b/bin/build_ocamlbuild new file mode 100755 index 0000000..fd6a2e4 --- /dev/null +++ b/bin/build_ocamlbuild @@ -0,0 +1 @@ +docker build -f DockerOcamlbuild -t ocaml:ocamlbuild . diff --git a/bin/run_ocamlbuild b/bin/run_ocamlbuild new file mode 100755 index 0000000..975813c --- /dev/null +++ b/bin/run_ocamlbuild @@ -0,0 +1,12 @@ +W=/workspace +# Create container +# BUILD="ocamlbuild -quiet -use-ocamlfind -pkgs 'ounit2,str,batteries' -I example test.native" +# BUILD="ocamlbuild -use-ocamlfind -pkgs 'ounit2,str,batteries' -I example test.native" +BUILD="ocamlbuild -use-ocamlfind test.native" +C=$(docker container create --rm -w $W ocaml:ocamlbuild sh -c "$BUILD && exec ./test.native") + +# Copy files +docker container cp ${1:-examples/basic}/. $C:$W + +# Start +docker container start --attach $C \ No newline at end of file From c248cc55bd145a669e59099ebedbdc40c3810e3f Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Mon, 3 Apr 2023 21:41:39 -0600 Subject: [PATCH 07/26] Rename test.ml to cwtest.ml and add an empty cwtest.mli --- DockerOcamlbuild | 3 ++- bin/run_ocamlbuild | 7 +++---- workspace/_tags | 4 ++-- workspace/{test.ml => cwtest.ml} | 0 workspace/cwtest.mli | 1 + 5 files changed, 8 insertions(+), 7 deletions(-) rename workspace/{test.ml => cwtest.ml} (100%) create mode 100644 workspace/cwtest.mli diff --git a/DockerOcamlbuild b/DockerOcamlbuild index c6b8f8c..2d4b42a 100644 --- a/DockerOcamlbuild +++ b/DockerOcamlbuild @@ -15,5 +15,6 @@ ENV USER=opam RUN sudo mkdir -p /workspace; \ sudo chown opam:opam /workspace -COPY workspace/test.ml /workspace/test.ml +COPY workspace/cwtest.ml /workspace/cwtest.ml +COPY workspace/cwtest.mli /workspace/cwtest.mli COPY workspace/_tags /workspace/_tags \ No newline at end of file diff --git a/bin/run_ocamlbuild b/bin/run_ocamlbuild index 975813c..4019565 100755 --- a/bin/run_ocamlbuild +++ b/bin/run_ocamlbuild @@ -1,9 +1,8 @@ W=/workspace # Create container -# BUILD="ocamlbuild -quiet -use-ocamlfind -pkgs 'ounit2,str,batteries' -I example test.native" -# BUILD="ocamlbuild -use-ocamlfind -pkgs 'ounit2,str,batteries' -I example test.native" -BUILD="ocamlbuild -use-ocamlfind test.native" -C=$(docker container create --rm -w $W ocaml:ocamlbuild sh -c "$BUILD && exec ./test.native") +# BUILD="ocamlbuild -quite -use-ocamlfind cwtest.native" +BUILD="ocamlbuild -use-ocamlfind cwtest.native" +C=$(docker container create --rm -w $W ocaml:ocamlbuild sh -c "$BUILD && exec ./cwtest.native") # Copy files docker container cp ${1:-examples/basic}/. $C:$W diff --git a/workspace/_tags b/workspace/_tags index 1ac93b4..2831990 100644 --- a/workspace/_tags +++ b/workspace/_tags @@ -1,3 +1,3 @@ - or or : package(ounit2) -not : package(batteries) + or or : package(ounit2) +not : package(batteries) # not : package(batteries), package(core) \ No newline at end of file diff --git a/workspace/test.ml b/workspace/cwtest.ml similarity index 100% rename from workspace/test.ml rename to workspace/cwtest.ml diff --git a/workspace/cwtest.mli b/workspace/cwtest.mli new file mode 100644 index 0000000..ec8b0b5 --- /dev/null +++ b/workspace/cwtest.mli @@ -0,0 +1 @@ +(* Nothing is exported *) \ No newline at end of file From 2efbb11175cd1c926b3da4e7e4e8d3d206c8e76f Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Tue, 4 Apr 2023 19:22:56 -0600 Subject: [PATCH 08/26] Improve the batteries example --- examples/batteries/preloaded.ml | 4 ++++ examples/batteries/solution.ml | 4 +++- examples/batteries/tests.ml | 13 ++++++++++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/examples/batteries/preloaded.ml b/examples/batteries/preloaded.ml index e69de29..14fcab2 100644 --- a/examples/batteries/preloaded.ml +++ b/examples/batteries/preloaded.ml @@ -0,0 +1,4 @@ +open Batteries + +let print_int = IO.to_string Int.print +let print_int_list = IO.to_string (List.print Int.print) \ No newline at end of file diff --git a/examples/batteries/solution.ml b/examples/batteries/solution.ml index 73b04e1..e59fc78 100644 --- a/examples/batteries/solution.ml +++ b/examples/batteries/solution.ml @@ -3,4 +3,6 @@ open Batteries let sum n = (1 -- n) |> Enum.map (fun i -> Num.num_of_int i |> Num.int_of_num) - |> Enum.sum \ No newline at end of file + |> Enum.sum + +let cubes = List.map Int.(fun x -> x ** 3) \ No newline at end of file diff --git a/examples/batteries/tests.ml b/examples/batteries/tests.ml index 9e21ec2..4b07fed 100644 --- a/examples/batteries/tests.ml +++ b/examples/batteries/tests.ml @@ -1,9 +1,16 @@ +open Batteries open OUnit +open Preloaded let suite = [ - "Fixed tests" >::: + "sum tests" >::: [ - "Testing 1" >:: (fun _ -> assert_equal 1 (Solution.sum 1) ~printer:string_of_int); - "Testing 10" >:: (fun _ -> assert_equal 45 (Solution.sum 9) ~printer:string_of_int); + "Testing 1" >:: (fun _ -> assert_equal 1 (Solution.sum 1) ~printer:print_int); + "Testing 9" >:: (fun _ -> assert_equal 45 (Solution.sum 9) ~printer:print_int); + ]; + "cubes tests" >::: + [ + "Testing [1; 2; 3]" >:: (fun _ -> assert_equal [1; 8; 27] (Solution.cubes ((1 -- 3) |> List.of_enum)) ~printer:print_int_list); + "Testing [5]" >:: (fun _ -> assert_equal [125] (Solution.cubes [5]) ~printer:print_int_list); ]; ] \ No newline at end of file From b323760b2149145e051e631ed8668d6788141702 Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Tue, 4 Apr 2023 19:27:44 -0600 Subject: [PATCH 09/26] Add the "compile-error" example --- examples/compile-error/solution.ml | 5 +++++ examples/compile-error/tests.ml | 9 +++++++++ 2 files changed, 14 insertions(+) create mode 100644 examples/compile-error/solution.ml create mode 100644 examples/compile-error/tests.ml diff --git a/examples/compile-error/solution.ml b/examples/compile-error/solution.ml new file mode 100644 index 0000000..ac637dd --- /dev/null +++ b/examples/compile-error/solution.ml @@ -0,0 +1,5 @@ +let sum n = + if n = 0 then + 0 + else + n + sum (n - 1) \ No newline at end of file diff --git a/examples/compile-error/tests.ml b/examples/compile-error/tests.ml new file mode 100644 index 0000000..772ae0a --- /dev/null +++ b/examples/compile-error/tests.ml @@ -0,0 +1,9 @@ +open OUnit + +let suite = [ + "sum tests" >::: + [ + "Testing 1" >:: (fun _ -> assert_equal 1 (Solution.sum 1) ~printer:string_of_int); + "Testing 9" >:: (fun _ -> assert_equal 45 (Solution.sum 9) ~printer:string_of_int); + ]; + ] \ No newline at end of file From b51bb85cdae10e84fd0e4f3e91628fd292590f14 Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Wed, 5 Apr 2023 11:40:44 -0600 Subject: [PATCH 10/26] Install the Base package --- DockerOcamlbuild | 2 +- workspace/_tags | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/DockerOcamlbuild b/DockerOcamlbuild index 2d4b42a..20e5a11 100644 --- a/DockerOcamlbuild +++ b/DockerOcamlbuild @@ -6,7 +6,7 @@ RUN set -ex; \ 'ounit2=2.2.7' \ 'ocamlbuild=0.14.2' \ 'batteries=3.6.0' \ -# 'core=v0.15.1' \ + 'base=v0.15.1' \ # '' ; diff --git a/workspace/_tags b/workspace/_tags index 2831990..9eed05e 100644 --- a/workspace/_tags +++ b/workspace/_tags @@ -1,3 +1,2 @@ or or : package(ounit2) -not : package(batteries) -# not : package(batteries), package(core) \ No newline at end of file +not : package(batteries), package(base) \ No newline at end of file From 2ad12d01d447da97a70c5dd93459dfef91d49f6d Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Wed, 5 Apr 2023 11:40:58 -0600 Subject: [PATCH 11/26] Add examples/base --- examples/base/preloaded.ml | 3 +++ examples/base/solution.ml | 3 +++ examples/base/tests.ml | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 examples/base/preloaded.ml create mode 100644 examples/base/solution.ml create mode 100644 examples/base/tests.ml diff --git a/examples/base/preloaded.ml b/examples/base/preloaded.ml new file mode 100644 index 0000000..d310ac6 --- /dev/null +++ b/examples/base/preloaded.ml @@ -0,0 +1,3 @@ +open Base + +let print_int_list = Fn.compose Sexp.to_string (sexp_of_list sexp_of_int) \ No newline at end of file diff --git a/examples/base/solution.ml b/examples/base/solution.ml new file mode 100644 index 0000000..08a2b1c --- /dev/null +++ b/examples/base/solution.ml @@ -0,0 +1,3 @@ +open Base + +let cubes = List.map ~f:Int.(fun x -> x ** 3) \ No newline at end of file diff --git a/examples/base/tests.ml b/examples/base/tests.ml new file mode 100644 index 0000000..f2c5882 --- /dev/null +++ b/examples/base/tests.ml @@ -0,0 +1,20 @@ +open Base +open OUnit +open Preloaded + +let suite = [ + (* "sum tests" >::: + [ + "Testing 1" >:: (fun _ -> assert_equal 1 (Solution.sum 1) ~printer:print_int); + "Testing 9" >:: (fun _ -> assert_equal 45 (Solution.sum 9) ~printer:print_int); + ]; *) + "cubes tests (passing)" >::: + [ + "Testing [1; 2; 3]" >:: (fun _ -> assert_equal [1; 8; 27] (Solution.cubes (List.range 1 4)) ~printer:print_int_list); + "Testing [5]" >:: (fun _ -> assert_equal [125] (Solution.cubes [5]) ~printer:print_int_list); + ]; + "cubes tests (failing)" >::: + [ + "Testing [1; 2; 3]" >:: (fun _ -> assert_equal [1; 8; 27] (Solution.cubes (List.range 1 5)) ~printer:print_int_list); + ]; + ] \ No newline at end of file From d58cd058821fce3b9f3a851640598264e0003473 Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Wed, 5 Apr 2023 12:27:32 -0600 Subject: [PATCH 12/26] Add the domainslib package --- DockerOcamlbuild | 8 +++++++- examples/base/tests.ml | 5 ----- workspace/_tags | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/DockerOcamlbuild b/DockerOcamlbuild index 20e5a11..23a6e77 100644 --- a/DockerOcamlbuild +++ b/DockerOcamlbuild @@ -1,5 +1,6 @@ FROM ocaml/opam:ubuntu-22.04-ocaml-5.0 +# Base packages RUN set -ex; \ eval $(opam env); \ opam install -y \ @@ -7,7 +8,12 @@ RUN set -ex; \ 'ocamlbuild=0.14.2' \ 'batteries=3.6.0' \ 'base=v0.15.1' \ -# '' + ; + +# Additional packages +RUN set -ex; \ + opam install -y \ + 'domainslib=0.5.0' \ ; USER opam diff --git a/examples/base/tests.ml b/examples/base/tests.ml index f2c5882..037e6f9 100644 --- a/examples/base/tests.ml +++ b/examples/base/tests.ml @@ -3,11 +3,6 @@ open OUnit open Preloaded let suite = [ - (* "sum tests" >::: - [ - "Testing 1" >:: (fun _ -> assert_equal 1 (Solution.sum 1) ~printer:print_int); - "Testing 9" >:: (fun _ -> assert_equal 45 (Solution.sum 9) ~printer:print_int); - ]; *) "cubes tests (passing)" >::: [ "Testing [1; 2; 3]" >:: (fun _ -> assert_equal [1; 8; 27] (Solution.cubes (List.range 1 4)) ~printer:print_int_list); diff --git a/workspace/_tags b/workspace/_tags index 9eed05e..5ec3439 100644 --- a/workspace/_tags +++ b/workspace/_tags @@ -1,2 +1,2 @@ or or : package(ounit2) -not : package(batteries), package(base) \ No newline at end of file +not : package(batteries), package(base), package(domainslib) \ No newline at end of file From cf1e83e1ad95fe5582baf398787411c923cacc7c Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Wed, 5 Apr 2023 12:27:46 -0600 Subject: [PATCH 13/26] Add examples/domainslib --- examples/domainslib/solution.ml | 17 +++++++++++++++++ examples/domainslib/tests.ml | 11 +++++++++++ 2 files changed, 28 insertions(+) create mode 100644 examples/domainslib/solution.ml create mode 100644 examples/domainslib/tests.ml diff --git a/examples/domainslib/solution.ml b/examples/domainslib/solution.ml new file mode 100644 index 0000000..c45299f --- /dev/null +++ b/examples/domainslib/solution.ml @@ -0,0 +1,17 @@ +(* Copied from https://github.com/kayceesrk/ocaml5-tutorial *) +module T = Domainslib.Task + +let rec fib0 n = if n < 2 then 1 else fib0 (n - 1) + fib0 (n - 2) + +let rec fib_par pool n = + if n > 20 then begin + let a = T.async pool (fun _ -> fib_par pool (n - 1)) in + let b = T.async pool (fun _ -> fib_par pool (n - 2)) in + T.await pool a + T.await pool b + end else fib0 n + +let fib num_domains n = + let pool = T.setup_pool ~num_domains:(num_domains - 1) () in + let res = T.run pool (fun _ -> fib_par pool n) in + T.teardown_pool pool; + res \ No newline at end of file diff --git a/examples/domainslib/tests.ml b/examples/domainslib/tests.ml new file mode 100644 index 0000000..9273299 --- /dev/null +++ b/examples/domainslib/tests.ml @@ -0,0 +1,11 @@ +open OUnit + +let suite = [ + "fib tests" >::: + [ + "Testing 42 (1 domain)" >:: (fun _ -> assert_equal 433494437 (Solution.fib 1 42) ~printer:string_of_int); + "Testing 42 (2 domains)" >:: (fun _ -> assert_equal 433494437 (Solution.fib 2 42) ~printer:string_of_int); + "Testing 42 (3 domains)" >:: (fun _ -> assert_equal 433494437 (Solution.fib 3 42) ~printer:string_of_int); + "Testing 42 (4 domains)" >:: (fun _ -> assert_equal 433494437 (Solution.fib 4 42) ~printer:string_of_int); + ]; + ] \ No newline at end of file From d8baf27ff9d0fbf3afbfdbe02e75e0e655085135 Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Wed, 5 Apr 2023 13:16:01 -0600 Subject: [PATCH 14/26] Add the zarith package --- DockerOcamlbuild | 2 ++ workspace/_tags | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/DockerOcamlbuild b/DockerOcamlbuild index 23a6e77..f4c7021 100644 --- a/DockerOcamlbuild +++ b/DockerOcamlbuild @@ -12,8 +12,10 @@ RUN set -ex; \ # Additional packages RUN set -ex; \ + opam depext 'zarith=1.12'; \ opam install -y \ 'domainslib=0.5.0' \ + 'zarith=1.12' \ ; USER opam diff --git a/workspace/_tags b/workspace/_tags index 5ec3439..4b035c2 100644 --- a/workspace/_tags +++ b/workspace/_tags @@ -1,2 +1,2 @@ or or : package(ounit2) -not : package(batteries), package(base), package(domainslib) \ No newline at end of file +not : package(batteries), package(base), package(domainslib), package(zarith) \ No newline at end of file From f8310b7c1b30b7b9dd2c72f7dbbe9d58ce1ddf1d Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Wed, 5 Apr 2023 13:16:14 -0600 Subject: [PATCH 15/26] Add examples/zarith --- examples/zarith/solution.ml | 10 ++++++++++ examples/zarith/tests.ml | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 examples/zarith/solution.ml create mode 100644 examples/zarith/tests.ml diff --git a/examples/zarith/solution.ml b/examples/zarith/solution.ml new file mode 100644 index 0000000..1f54f94 --- /dev/null +++ b/examples/zarith/solution.ml @@ -0,0 +1,10 @@ +let fib_zarith n = + let rec fib n a b = + if n = 0 then a else fib (n - 1) b (Z.add a b) in + Z.rem (fib n Z.zero Z.one) (Z.of_int 1000007) + +let fib_num n = + let open Big_int in + let rec fib n a b = + if n = 0 then a else fib (n - 1) b (add_big_int a b) in + mod_big_int (fib n zero_big_int unit_big_int) (big_int_of_int 1000007) \ No newline at end of file diff --git a/examples/zarith/tests.ml b/examples/zarith/tests.ml new file mode 100644 index 0000000..3dd13e0 --- /dev/null +++ b/examples/zarith/tests.ml @@ -0,0 +1,16 @@ +open OUnit + +let suite = [ + "fib_zarith tests" >::: + [ + "Testing 42" >:: (fun _ -> assert_equal (Z.of_int 912427) (Solution.fib_zarith 42) ~cmp:Z.equal ~printer:Z.to_string); + "Testing 100000" >:: (fun _ -> assert_equal (Z.of_int 584523) (Solution.fib_zarith 100000) ~cmp:Z.equal ~printer:Z.to_string); + "Testing 1000000" >:: (fun _ -> assert_equal (Z.of_int 930254) (Solution.fib_zarith 1000000) ~cmp:Z.equal ~printer:Z.to_string); + ]; + "fib_num tests" >::: + [ + "Testing 42" >:: (fun _ -> assert_equal (Big_int.big_int_of_int 912427) (Solution.fib_num 42) ~cmp:Big_int.eq_big_int ~printer:Big_int.string_of_big_int); + "Testing 100000" >:: (fun _ -> assert_equal (Big_int.big_int_of_int 584523) (Solution.fib_num 100000) ~cmp:Big_int.eq_big_int ~printer:Big_int.string_of_big_int); + "Testing 1000000" >:: (fun _ -> assert_equal (Big_int.big_int_of_int 930254) (Solution.fib_num 1000000) ~cmp:Big_int.eq_big_int ~printer:Big_int.string_of_big_int); + ]; + ] \ No newline at end of file From 38c1d6c23f05b726ccd9d88d0793e4d74cbaed67 Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Wed, 5 Apr 2023 20:33:10 -0600 Subject: [PATCH 16/26] Use a multistage docker build --- DockerOcamlbuild | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/DockerOcamlbuild b/DockerOcamlbuild index f4c7021..aefe5fc 100644 --- a/DockerOcamlbuild +++ b/DockerOcamlbuild @@ -1,4 +1,4 @@ -FROM ocaml/opam:ubuntu-22.04-ocaml-5.0 +FROM ocaml/opam:ubuntu-22.04-ocaml-5.0 AS builder # Base packages RUN set -ex; \ @@ -18,11 +18,42 @@ RUN set -ex; \ 'zarith=1.12' \ ; -USER opam -ENV USER=opam +FROM ubuntu:22.04 -RUN sudo mkdir -p /workspace; \ - sudo chown opam:opam /workspace -COPY workspace/cwtest.ml /workspace/cwtest.ml -COPY workspace/cwtest.mli /workspace/cwtest.mli -COPY workspace/_tags /workspace/_tags \ No newline at end of file +RUN set -ex; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + gcc \ + libc6-dev \ + libgmp-dev \ + ; \ + rm -rf /var/lib/apt/lists/*; + +COPY --from=builder \ + /home/opam/.opam/5.0/bin/ocamlc.opt \ + /home/opam/.opam/5.0/bin/ocamlopt.opt \ + /home/opam/.opam/5.0/bin/ocamldep.opt \ + /home/opam/.opam/5.0/bin/ocamlbuild \ + /home/opam/.opam/5.0/bin/ocamlfind \ + /home/opam/.opam/5.0/bin/ + +COPY --from=builder /home/opam/.opam/5.0/lib/ /home/opam/.opam/5.0/lib/ + +RUN set -ex; \ + useradd --create-home codewarrior; \ + mkdir -p /workspace; \ + chown codewarrior: /workspace; + +USER codewarrior +ENV USER=codewarrior \ + PATH=/home/opam/.opam/5.0/bin:$PATH + +COPY --chown=codewarrior:codewarrior workspace/. /workspace/ +WORKDIR /workspace +# COPY --chown=codewarrior:codewarrior examples/batteries/. /workspace/ + + +# RUN OPAM_SWITCH_PREFIX='/home/opam/.opam/5.0'; export OPAM_SWITCH_PREFIX; \ +# CAML_LD_LIBRARY_PATH='/home/opam/.opam/5.0/lib/stublibs:/home/opam/.opam/5.0/lib/ocaml/stublibs:/home/opam/.opam/5.0/lib/ocaml'; export CAML_LD_LIBRARY_PATH; \ +# OCAML_TOPLEVEL_PATH='/home/opam/.opam/5.0/lib/toplevel'; export OCAML_TOPLEVEL_PATH; \ +# PATH='/home/opam/.opam/5.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'; export PATH; \ No newline at end of file From 880e33235e9bdb8ea6ef218199555a318e883cf0 Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Thu, 6 Apr 2023 22:11:05 -0600 Subject: [PATCH 17/26] Dockerfile: manually install opam and use Alpine-3.17 --- Dockerfile | 77 +++++++++++++++++++++++++++++++------------------ workspace/_tags | 2 +- 2 files changed, 50 insertions(+), 29 deletions(-) diff --git a/Dockerfile b/Dockerfile index 009d973..ee0648b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,42 +1,63 @@ -FROM ubuntu:22.04 +FROM alpine:3.17 AS builder -RUN set -ex; \ - useradd --create-home codewarrior; \ - mkdir -p /workspace; \ - chown -R codewarrior:codewarrior /workspace; - -ENV OPAMROOT=/opt/opam \ - OPAMCOLOR=never +ENV OPAMROOT=/opt/ocaml RUN set -ex; \ mkdir -p $OPAMROOT; \ - chown codewarrior:codewarrior $OPAMROOT; \ - apt-get update; \ - apt-get install -y --no-install-recommends \ - software-properties-common \ - libgmp-dev \ + adduser -D codewarrior; \ + chown -R codewarrior:codewarrior /opt/ocaml; \ + apk update; \ + apk add --virtual .build-deps \ + build-base \ + ocaml-compiler-libs \ + gmp-dev \ opam \ ; USER codewarrior -ENV USER=codewarrior \ - HOME=/home/codewarrior +ENV USER=codewarrior -RUN opam init -y --shell-setup --compiler=4.14.0 --disable-sandboxing +RUN set -ex; \ + opam init -y --disable-sandboxing --compiler=5.0.0; -RUN opam install -y \ - 'ounit2=2.2.6' \ - 'ocamlfind=1.9.3' \ - 'ocamlbuild=0.14.1' \ +RUN set -ex; \ + opam install -y \ + 'batteries=3.6.0' \ + 'base=v0.15.1' \ + 'domainslib=0.5.0' \ + 'ocamlbuild=0.14.2' \ + 'ocamlfind=1.9.6' \ + 'ounit2=2.2.7' \ 'zarith=1.12' \ - 'batteries=3.5.1' \ - 'core=v0.15.0' \ ; -ENV OPAM_SWITCH_PREFIX=$OPAMROOT/4.14.0 \ - CAML_LD_LIBRARY_PATH=$OPAMROOT/4.14.0/lib/stublibs:$OPAMROOT/4.14.0/lib/ocaml/stublibs:$OPAMROOT/4.14.0/lib/ocaml \ - OCAML_TOPLEVEL_PATH=$OPAMROOT/4.14.0/lib/toplevel \ - PATH=$OPAMROOT/4.14.0/bin:$PATH +FROM alpine:3.17 + +RUN set -ex; \ + apk add --no-cache \ + gcc \ + gmp-dev \ + musl-dev \ + ; + +COPY --from=builder \ + /opt/ocaml/5.0.0/bin/ocamlc.opt \ + /opt/ocaml/5.0.0/bin/ocamlopt.opt \ + /opt/ocaml/5.0.0/bin/ocamldep.opt \ + /opt/ocaml/5.0.0/bin/ocamlbuild \ + /opt/ocaml/5.0.0/bin/ocamlfind \ + /opt/ocaml/5.0.0/bin/ +COPY --from=builder \ + /opt/ocaml/5.0.0/lib/ /opt/ocaml/5.0.0/lib/ + +RUN set -ex; \ + adduser -D codewarrior; \ + mkdir /workspace; \ + chown -R codewarrior:codewarrior /workspace; + +USER codewarrior +ENV USER=codewarrior \ + PATH=/opt/ocaml/5.0.0/bin:$PATH -COPY workspace/test.ml /workspace/test.ml -COPY workspace/_tags /workspace/_tags \ No newline at end of file +COPY --chown=codewarrior:codewarrior workspace/. /workspace/ +WORKDIR /workspace\ \ No newline at end of file diff --git a/workspace/_tags b/workspace/_tags index 4b035c2..793ddb0 100644 --- a/workspace/_tags +++ b/workspace/_tags @@ -1,2 +1,2 @@ or or : package(ounit2) -not : package(batteries), package(base), package(domainslib), package(zarith) \ No newline at end of file +not : thread, package(batteries), package(base), package(domainslib), package(zarith) \ No newline at end of file From bbde56cbb59e0d224768bf57fbf713cdfbfb3bf7 Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Sun, 9 Apr 2023 17:38:18 -0600 Subject: [PATCH 18/26] Misc updates --- Dockerfile | 2 +- workspace/cwtest.ml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index ee0648b..02a8f74 100644 --- a/Dockerfile +++ b/Dockerfile @@ -60,4 +60,4 @@ ENV USER=codewarrior \ PATH=/opt/ocaml/5.0.0/bin:$PATH COPY --chown=codewarrior:codewarrior workspace/. /workspace/ -WORKDIR /workspace\ \ No newline at end of file +WORKDIR /workspace \ No newline at end of file diff --git a/workspace/cwtest.ml b/workspace/cwtest.ml index 6f25109..f433715 100644 --- a/workspace/cwtest.ml +++ b/workspace/cwtest.ml @@ -55,5 +55,4 @@ and run_test = function and run_tests tests = List.iter run_test tests -(* `solution` and `fixture` are concatenated to `fixture.ml` *) let () = run_tests Tests.suite From da9c27ffb0054ed6192d64abea7a6817f9e7278d Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Sun, 9 Apr 2023 17:38:47 -0600 Subject: [PATCH 19/26] Add bin/build and bin/run for building and running ocaml:latest --- bin/build | 1 + bin/run | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100755 bin/build create mode 100755 bin/run diff --git a/bin/build b/bin/build new file mode 100755 index 0000000..55567b6 --- /dev/null +++ b/bin/build @@ -0,0 +1 @@ +docker build -t ocaml:latest . diff --git a/bin/run b/bin/run new file mode 100755 index 0000000..a74ce51 --- /dev/null +++ b/bin/run @@ -0,0 +1,10 @@ +W=/workspace +# Create container +BUILD="ocamlbuild -quiet -use-ocamlfind cwtest.native" +C=$(docker container create --rm -w $W ocaml:latest sh -c "$BUILD && exec ./cwtest.native") + +# Copy files +docker container cp ${1:-examples/basic}/. $C:$W + +# Start +docker container start --attach $C \ No newline at end of file From ee8dcf3d9bb5908bf30b739175bb690a0b91be26 Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Sun, 9 Apr 2023 17:39:00 -0600 Subject: [PATCH 20/26] Add examples/unix --- examples/unix/solution.ml | 1 + examples/unix/tests.ml | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 examples/unix/solution.ml create mode 100644 examples/unix/tests.ml diff --git a/examples/unix/solution.ml b/examples/unix/solution.ml new file mode 100644 index 0000000..be8f2fa --- /dev/null +++ b/examples/unix/solution.ml @@ -0,0 +1 @@ +let getenv = Unix.environment \ No newline at end of file diff --git a/examples/unix/tests.ml b/examples/unix/tests.ml new file mode 100644 index 0000000..e4818e0 --- /dev/null +++ b/examples/unix/tests.ml @@ -0,0 +1,9 @@ +open OUnit +open Batteries + +let suite = [ + "getenv" >::: + [ + "Test" >:: (fun _ -> assert_equal [||] (Solution.getenv ()) ~printer:(IO.to_string @@ Array.print String.print_quoted)); + ]; + ] \ No newline at end of file From 579a5ee815ac045c2aebba965d2de881526e8ce4 Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Sun, 9 Apr 2023 17:59:07 -0600 Subject: [PATCH 21/26] Add Ubuntu image files --- DockerOcamlbuild | 59 ---------------------------------------- DockerfileUbuntu | 64 ++++++++++++++++++++++++++++++++++++++++++++ bin/build | 2 +- bin/build_ocamlbuild | 1 - bin/run | 2 +- bin/run_ocamlbuild | 11 -------- bin/ubuntu_build | 1 + bin/ubuntu_run | 10 +++++++ 8 files changed, 77 insertions(+), 73 deletions(-) delete mode 100644 DockerOcamlbuild create mode 100644 DockerfileUbuntu delete mode 100755 bin/build_ocamlbuild delete mode 100755 bin/run_ocamlbuild create mode 100755 bin/ubuntu_build create mode 100755 bin/ubuntu_run diff --git a/DockerOcamlbuild b/DockerOcamlbuild deleted file mode 100644 index aefe5fc..0000000 --- a/DockerOcamlbuild +++ /dev/null @@ -1,59 +0,0 @@ -FROM ocaml/opam:ubuntu-22.04-ocaml-5.0 AS builder - -# Base packages -RUN set -ex; \ - eval $(opam env); \ - opam install -y \ - 'ounit2=2.2.7' \ - 'ocamlbuild=0.14.2' \ - 'batteries=3.6.0' \ - 'base=v0.15.1' \ - ; - -# Additional packages -RUN set -ex; \ - opam depext 'zarith=1.12'; \ - opam install -y \ - 'domainslib=0.5.0' \ - 'zarith=1.12' \ - ; - -FROM ubuntu:22.04 - -RUN set -ex; \ - apt-get update; \ - apt-get install -y --no-install-recommends \ - gcc \ - libc6-dev \ - libgmp-dev \ - ; \ - rm -rf /var/lib/apt/lists/*; - -COPY --from=builder \ - /home/opam/.opam/5.0/bin/ocamlc.opt \ - /home/opam/.opam/5.0/bin/ocamlopt.opt \ - /home/opam/.opam/5.0/bin/ocamldep.opt \ - /home/opam/.opam/5.0/bin/ocamlbuild \ - /home/opam/.opam/5.0/bin/ocamlfind \ - /home/opam/.opam/5.0/bin/ - -COPY --from=builder /home/opam/.opam/5.0/lib/ /home/opam/.opam/5.0/lib/ - -RUN set -ex; \ - useradd --create-home codewarrior; \ - mkdir -p /workspace; \ - chown codewarrior: /workspace; - -USER codewarrior -ENV USER=codewarrior \ - PATH=/home/opam/.opam/5.0/bin:$PATH - -COPY --chown=codewarrior:codewarrior workspace/. /workspace/ -WORKDIR /workspace -# COPY --chown=codewarrior:codewarrior examples/batteries/. /workspace/ - - -# RUN OPAM_SWITCH_PREFIX='/home/opam/.opam/5.0'; export OPAM_SWITCH_PREFIX; \ -# CAML_LD_LIBRARY_PATH='/home/opam/.opam/5.0/lib/stublibs:/home/opam/.opam/5.0/lib/ocaml/stublibs:/home/opam/.opam/5.0/lib/ocaml'; export CAML_LD_LIBRARY_PATH; \ -# OCAML_TOPLEVEL_PATH='/home/opam/.opam/5.0/lib/toplevel'; export OCAML_TOPLEVEL_PATH; \ -# PATH='/home/opam/.opam/5.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'; export PATH; \ No newline at end of file diff --git a/DockerfileUbuntu b/DockerfileUbuntu new file mode 100644 index 0000000..47c9a04 --- /dev/null +++ b/DockerfileUbuntu @@ -0,0 +1,64 @@ +FROM ubuntu:22.04 AS Builder + +ENV OPAMROOT=/opt/ocaml + +RUN set -ex; \ + mkdir -p $OPAMROOT; \ + useradd --create-home codewarrior; \ + chown codewarrior:codewarrior $OPAMROOT; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + software-properties-common \ + libgmp-dev \ + opam \ + ; + +USER codewarrior +ENV USER=codewarrior + +RUN set -ex; \ + opam init -y --disable-sandboxing --compiler=5.0.0; + +RUN set -ex; \ + opam install -y \ + 'batteries=3.6.0' \ + 'base=v0.15.1' \ + 'domainslib=0.5.0' \ + 'ocamlbuild=0.14.2' \ + 'ocamlfind=1.9.6' \ + 'ounit2=2.2.7' \ + 'zarith=1.12' \ + ; + +FROM ubuntu:22.04 + +RUN set -ex; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + gcc \ + libc6-dev \ + libgmp-dev \ + ; \ + rm -rf /var/lib/apt/lists/*; + +COPY --from=builder \ + /opt/ocaml/5.0.0/bin/ocamlc.opt \ + /opt/ocaml/5.0.0/bin/ocamlopt.opt \ + /opt/ocaml/5.0.0/bin/ocamldep.opt \ + /opt/ocaml/5.0.0/bin/ocamlbuild \ + /opt/ocaml/5.0.0/bin/ocamlfind \ + /opt/ocaml/5.0.0/bin/ +COPY --from=builder \ + /opt/ocaml/5.0.0/lib/ /opt/ocaml/5.0.0/lib/ + +RUN set -ex; \ + useradd --create-home codewarrior; \ + mkdir -p /workspace; \ + chown -R codewarrior:codewarrior /workspace; + +USER codewarrior +ENV USER=codewarrior \ + PATH=/opt/ocaml/5.0.0/bin:$PATH + +COPY --chown=codewarrior:codewarrior workspace/. /workspace/ +WORKDIR /workspace diff --git a/bin/build b/bin/build index 55567b6..65fe529 100755 --- a/bin/build +++ b/bin/build @@ -1 +1 @@ -docker build -t ocaml:latest . +docker build -t ocaml:alpine . diff --git a/bin/build_ocamlbuild b/bin/build_ocamlbuild deleted file mode 100755 index fd6a2e4..0000000 --- a/bin/build_ocamlbuild +++ /dev/null @@ -1 +0,0 @@ -docker build -f DockerOcamlbuild -t ocaml:ocamlbuild . diff --git a/bin/run b/bin/run index a74ce51..789bd20 100755 --- a/bin/run +++ b/bin/run @@ -1,7 +1,7 @@ W=/workspace # Create container BUILD="ocamlbuild -quiet -use-ocamlfind cwtest.native" -C=$(docker container create --rm -w $W ocaml:latest sh -c "$BUILD && exec ./cwtest.native") +C=$(docker container create --rm -w $W ocaml:alpine sh -c "$BUILD && exec ./cwtest.native") # Copy files docker container cp ${1:-examples/basic}/. $C:$W diff --git a/bin/run_ocamlbuild b/bin/run_ocamlbuild deleted file mode 100755 index 4019565..0000000 --- a/bin/run_ocamlbuild +++ /dev/null @@ -1,11 +0,0 @@ -W=/workspace -# Create container -# BUILD="ocamlbuild -quite -use-ocamlfind cwtest.native" -BUILD="ocamlbuild -use-ocamlfind cwtest.native" -C=$(docker container create --rm -w $W ocaml:ocamlbuild sh -c "$BUILD && exec ./cwtest.native") - -# Copy files -docker container cp ${1:-examples/basic}/. $C:$W - -# Start -docker container start --attach $C \ No newline at end of file diff --git a/bin/ubuntu_build b/bin/ubuntu_build new file mode 100755 index 0000000..72fe7a7 --- /dev/null +++ b/bin/ubuntu_build @@ -0,0 +1 @@ +docker build -f DockerfileUbuntu -t ocaml:ubuntu . diff --git a/bin/ubuntu_run b/bin/ubuntu_run new file mode 100755 index 0000000..35afac3 --- /dev/null +++ b/bin/ubuntu_run @@ -0,0 +1,10 @@ +W=/workspace +# Create container +BUILD="ocamlbuild -quiet -use-ocamlfind cwtest.native" +C=$(docker container create --rm -w $W ocaml:ubuntu sh -c "$BUILD && exec ./cwtest.native") + +# Copy files +docker container cp ${1:-examples/basic}/. $C:$W + +# Start +docker container start --attach $C \ No newline at end of file From d4ea086eac5cf82ecc67cd2199e034b6ce6fd39f Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Sun, 9 Apr 2023 18:01:00 -0600 Subject: [PATCH 22/26] Update README --- README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8074172..44c20c1 100644 --- a/README.md +++ b/README.md @@ -5,16 +5,15 @@ Container image for OCaml used by CodeRunner. ## Usage ```bash -W=/workspace/ +W=/workspace # Create container -C=$(docker container create --rm -w $W ghcr.io/codewars/ocaml:latest \ - sh -c 'ocamlbuild -quiet -use-ocamlfind test.native && exec ./test.native') +BUILD="ocamlbuild -quiet -use-ocamlfind cwtest.native" +C=$(docker container create --rm -w $W ghcr.io/codewars/ocaml:latest sh -c "$BUILD && exec ./cwtest.native") -# Write solution and tests in workspace/fixture.ml -# Then copy it inside a container -docker container cp workspace/fixture.ml $C:$W/fixture.ml +# Copy solution and test files +docker container cp ${1:-examples/basic}/. $C:$W -# Run tests +# Start docker container start --attach $C ``` From e79d85383cad61f3fef5bbdd1649e91f92e52d46 Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Sun, 9 Apr 2023 20:07:55 -0600 Subject: [PATCH 23/26] Update _tags: include ounit2 for all targets except solution.ml --- workspace/_tags | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workspace/_tags b/workspace/_tags index 793ddb0..aba10ca 100644 --- a/workspace/_tags +++ b/workspace/_tags @@ -1,2 +1,2 @@ - or or : package(ounit2) -not : thread, package(batteries), package(base), package(domainslib), package(zarith) \ No newline at end of file +not : package(ounit2) +not : thread, package(batteries), package(base), package(domainslib), package(zarith) \ No newline at end of file From 6979f91d73e4ac2202e906713aee371e4705dc4a Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Mon, 17 Apr 2023 19:18:30 -0600 Subject: [PATCH 24/26] Ubuntu is the default image --- Dockerfile | 33 ++++++++++++++-------------- DockerfileUbuntu => DockerfileAlpine | 33 ++++++++++++++-------------- bin/alpine_build | 1 + bin/alpine_run | 2 ++ bin/build | 2 +- bin/run | 8 ++++++- bin/ubuntu_build | 1 - bin/ubuntu_run | 10 --------- 8 files changed, 44 insertions(+), 46 deletions(-) rename DockerfileUbuntu => DockerfileAlpine (66%) create mode 100755 bin/alpine_build create mode 100755 bin/alpine_run delete mode 100755 bin/ubuntu_build delete mode 100755 bin/ubuntu_run diff --git a/Dockerfile b/Dockerfile index 02a8f74..47c9a04 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,15 @@ -FROM alpine:3.17 AS builder +FROM ubuntu:22.04 AS Builder ENV OPAMROOT=/opt/ocaml RUN set -ex; \ mkdir -p $OPAMROOT; \ - adduser -D codewarrior; \ - chown -R codewarrior:codewarrior /opt/ocaml; \ - apk update; \ - apk add --virtual .build-deps \ - build-base \ - ocaml-compiler-libs \ - gmp-dev \ + useradd --create-home codewarrior; \ + chown codewarrior:codewarrior $OPAMROOT; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + software-properties-common \ + libgmp-dev \ opam \ ; @@ -31,14 +30,16 @@ RUN set -ex; \ 'zarith=1.12' \ ; -FROM alpine:3.17 +FROM ubuntu:22.04 RUN set -ex; \ - apk add --no-cache \ + apt-get update; \ + apt-get install -y --no-install-recommends \ gcc \ - gmp-dev \ - musl-dev \ - ; + libc6-dev \ + libgmp-dev \ + ; \ + rm -rf /var/lib/apt/lists/*; COPY --from=builder \ /opt/ocaml/5.0.0/bin/ocamlc.opt \ @@ -51,8 +52,8 @@ COPY --from=builder \ /opt/ocaml/5.0.0/lib/ /opt/ocaml/5.0.0/lib/ RUN set -ex; \ - adduser -D codewarrior; \ - mkdir /workspace; \ + useradd --create-home codewarrior; \ + mkdir -p /workspace; \ chown -R codewarrior:codewarrior /workspace; USER codewarrior @@ -60,4 +61,4 @@ ENV USER=codewarrior \ PATH=/opt/ocaml/5.0.0/bin:$PATH COPY --chown=codewarrior:codewarrior workspace/. /workspace/ -WORKDIR /workspace \ No newline at end of file +WORKDIR /workspace diff --git a/DockerfileUbuntu b/DockerfileAlpine similarity index 66% rename from DockerfileUbuntu rename to DockerfileAlpine index 47c9a04..02a8f74 100644 --- a/DockerfileUbuntu +++ b/DockerfileAlpine @@ -1,15 +1,16 @@ -FROM ubuntu:22.04 AS Builder +FROM alpine:3.17 AS builder ENV OPAMROOT=/opt/ocaml RUN set -ex; \ mkdir -p $OPAMROOT; \ - useradd --create-home codewarrior; \ - chown codewarrior:codewarrior $OPAMROOT; \ - apt-get update; \ - apt-get install -y --no-install-recommends \ - software-properties-common \ - libgmp-dev \ + adduser -D codewarrior; \ + chown -R codewarrior:codewarrior /opt/ocaml; \ + apk update; \ + apk add --virtual .build-deps \ + build-base \ + ocaml-compiler-libs \ + gmp-dev \ opam \ ; @@ -30,16 +31,14 @@ RUN set -ex; \ 'zarith=1.12' \ ; -FROM ubuntu:22.04 +FROM alpine:3.17 RUN set -ex; \ - apt-get update; \ - apt-get install -y --no-install-recommends \ + apk add --no-cache \ gcc \ - libc6-dev \ - libgmp-dev \ - ; \ - rm -rf /var/lib/apt/lists/*; + gmp-dev \ + musl-dev \ + ; COPY --from=builder \ /opt/ocaml/5.0.0/bin/ocamlc.opt \ @@ -52,8 +51,8 @@ COPY --from=builder \ /opt/ocaml/5.0.0/lib/ /opt/ocaml/5.0.0/lib/ RUN set -ex; \ - useradd --create-home codewarrior; \ - mkdir -p /workspace; \ + adduser -D codewarrior; \ + mkdir /workspace; \ chown -R codewarrior:codewarrior /workspace; USER codewarrior @@ -61,4 +60,4 @@ ENV USER=codewarrior \ PATH=/opt/ocaml/5.0.0/bin:$PATH COPY --chown=codewarrior:codewarrior workspace/. /workspace/ -WORKDIR /workspace +WORKDIR /workspace \ No newline at end of file diff --git a/bin/alpine_build b/bin/alpine_build new file mode 100755 index 0000000..46aaf2f --- /dev/null +++ b/bin/alpine_build @@ -0,0 +1 @@ +docker build -f DockerfileAlpine -t ocaml:alpine . diff --git a/bin/alpine_run b/bin/alpine_run new file mode 100755 index 0000000..9916aa3 --- /dev/null +++ b/bin/alpine_run @@ -0,0 +1,2 @@ +export IMAGE=ocaml:alpine +exec "$(dirname "$0")/run" "$@" \ No newline at end of file diff --git a/bin/build b/bin/build index 65fe529..1115753 100755 --- a/bin/build +++ b/bin/build @@ -1 +1 @@ -docker build -t ocaml:alpine . +docker build -t ghcr.io/codewars/ocaml:latest . \ No newline at end of file diff --git a/bin/run b/bin/run index 789bd20..2b90fb7 100755 --- a/bin/run +++ b/bin/run @@ -1,7 +1,13 @@ +set -eu + +if [ -z "${IMAGE:+x}" ]; then + IMAGE=ghcr.io/codewars/ocaml:latest +fi + W=/workspace # Create container BUILD="ocamlbuild -quiet -use-ocamlfind cwtest.native" -C=$(docker container create --rm -w $W ocaml:alpine sh -c "$BUILD && exec ./cwtest.native") +C=$(docker container create --rm -w $W $IMAGE sh -c "$BUILD && exec ./cwtest.native") # Copy files docker container cp ${1:-examples/basic}/. $C:$W diff --git a/bin/ubuntu_build b/bin/ubuntu_build deleted file mode 100755 index 72fe7a7..0000000 --- a/bin/ubuntu_build +++ /dev/null @@ -1 +0,0 @@ -docker build -f DockerfileUbuntu -t ocaml:ubuntu . diff --git a/bin/ubuntu_run b/bin/ubuntu_run deleted file mode 100755 index 35afac3..0000000 --- a/bin/ubuntu_run +++ /dev/null @@ -1,10 +0,0 @@ -W=/workspace -# Create container -BUILD="ocamlbuild -quiet -use-ocamlfind cwtest.native" -C=$(docker container create --rm -w $W ocaml:ubuntu sh -c "$BUILD && exec ./cwtest.native") - -# Copy files -docker container cp ${1:-examples/basic}/. $C:$W - -# Start -docker container start --attach $C \ No newline at end of file From 27e09b3baa8d5aa504b8f90fcb4250d40cd44204 Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Mon, 17 Apr 2023 19:25:01 -0600 Subject: [PATCH 25/26] Add workflows/ci.yml --- .github/workflows/ci.yml | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..ccfa850 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,42 @@ +name: CI +on: + push: + branches: + - main + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + if: ${{ github.repository == 'codewars/ocaml' }} + steps: + - uses: actions/checkout@v2 + - uses: docker/setup-buildx-action@v2 + + - name: Build image + uses: docker/build-push-action@v3 + with: + context: . + push: false + # Make the image available in next step + load: true + tags: ghcr.io/codewars/ocaml:latest + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Run Batteries Example + run: bin/run examples/batteries + + - name: Run Base Example (with failing tests) + run: bin/run examples/base + + - name: Run Domainslib Example + run: bin/run examples/domainslib + + - name: Run Zartih Example + run: bin/run examples/zarith + + - name: Report Image Size + run: | + echo "## Image Size" >> $GITHUB_STEP_SUMMARY + docker image inspect --format '{{.Size}}' ghcr.io/codewars/ocaml:latest | numfmt --to=si --suffix=B >> $GITHUB_STEP_SUMMARY From 3a492d016affea8818a1009c96ecf2fee903b9be Mon Sep 17 00:00:00 2001 From: Alexey Solovyev Date: Mon, 17 Apr 2023 19:38:04 -0600 Subject: [PATCH 26/26] Add "--shell-setup" to "opam init" --- .github/workflows/ci.yml | 2 +- Dockerfile | 2 +- DockerfileAlpine | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ccfa850..241f34e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: - name: Run Domainslib Example run: bin/run examples/domainslib - - name: Run Zartih Example + - name: Run Zarith Example run: bin/run examples/zarith - name: Report Image Size diff --git a/Dockerfile b/Dockerfile index 47c9a04..005abd5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,7 @@ USER codewarrior ENV USER=codewarrior RUN set -ex; \ - opam init -y --disable-sandboxing --compiler=5.0.0; + opam init -y --shell-setup --disable-sandboxing --compiler=5.0.0; RUN set -ex; \ opam install -y \ diff --git a/DockerfileAlpine b/DockerfileAlpine index 02a8f74..ad32207 100644 --- a/DockerfileAlpine +++ b/DockerfileAlpine @@ -18,7 +18,7 @@ USER codewarrior ENV USER=codewarrior RUN set -ex; \ - opam init -y --disable-sandboxing --compiler=5.0.0; + opam init -y --shell-setup --disable-sandboxing --compiler=5.0.0; RUN set -ex; \ opam install -y \