Skip to content

Commit

Permalink
refactor: Get rid of the pseudo-cipher
Browse files Browse the repository at this point in the history
Finally :)

This should give a nice economy of bandwidth since the unciphered compilation
artifacts will compress much better.
  • Loading branch information
AltGr committed Nov 3, 2023
1 parent 47d5a06 commit 2792faf
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 139 deletions.
2 changes: 1 addition & 1 deletion src/grader/grader_cli.ml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ let read_exercise exercise_dir =
in
Learnocaml_exercise.read_lwt ~read_field
~id:(Filename.basename exercise_dir)
~decipher:false ()
()

let remove_trailing_slash s =
let len = String.length s in
Expand Down
2 changes: 1 addition & 1 deletion src/repo/dune
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
(modules Learnocaml_index
Learnocaml_exercise)
(libraries ocplib-json-typed
learnocaml_xor
base64
omd
lwt
ezjsonm)
Expand Down
100 changes: 36 additions & 64 deletions src/repo/learnocaml_exercise.ml
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,19 @@ type t =

let encoding =
let open Json_encoding in
let b64 =
(* TODO: try to use the native implementation on browsers ? *)
conv
(fun s -> Base64.encode_string s)
(fun b -> Result.get_ok (Base64.decode b))
string
in
let compiled_lib_encoding =
conv
(fun {cma; js} -> cma, js)
(fun (cma, js) -> {cma; js})
(obj2
(dft "cma" string "")
(dft "cma" b64 "")
(dft "js" string ""))
in
let compiled_encoding =
Expand All @@ -49,10 +56,10 @@ let encoding =
(fun (prelude_cmi, prepare_cmi, solution_cmi, test_cmi, exercise_lib, test_lib) ->
{prelude_cmi; prepare_cmi; solution_cmi; test_cmi; exercise_lib; test_lib})
(obj6
(req "prelude_cmi" string)
(req "prepare_cmi" string)
(req "solution_cmi" string)
(req "test_cmi" string)
(req "prelude_cmi" b64)
(req "prepare_cmi" b64)
(req "solution_cmi" b64)
(req "test_cmi" b64)
(req "exercise_lib" compiled_lib_encoding)
(req "test_lib" compiled_lib_encoding))
in
Expand Down Expand Up @@ -116,7 +123,6 @@ module File = struct

type 'a file =
{ key : string ;
ciphered : bool ;
decode : string -> 'a ;
encode : 'a -> string ;
field : t -> 'a ;
Expand All @@ -125,15 +131,10 @@ module File = struct

exception Missing_file of string

let get { key ; ciphered ; decode ; _ } ex =
let get { key ; decode ; _ } ex =
try
let raw = StringMap.find key ex in
if ciphered then
let prefix =
Digest.string (StringMap.find "id" ex ^ "_" ^ key) in
decode (Learnocaml_xor.decode ~prefix raw)
else
decode raw
decode raw
with Not_found -> raise (Missing_file ("get " ^ key))

let get_opt file ex =
Expand All @@ -144,18 +145,13 @@ module File = struct
let has { key ; _ } ex =
StringMap.mem key ex

let set { key ; ciphered ; encode ; _ } raw ex =
if ciphered then
let prefix =
Digest.string (StringMap.find "id" ex ^ "_" ^ key) in
StringMap.add key (Learnocaml_xor.encode ~prefix (encode raw)) ex
else
StringMap.add key (encode raw) ex
let set { key ; encode ; _ } raw ex =
StringMap.add key (encode raw) ex

let key file = file.key

let id =
{ key = "id" ; ciphered = false ;
{ key = "id" ;
decode = (fun v -> v) ; encode = (fun v -> v) ;
field = (fun ex -> ex.id) ;
update = (fun id ex -> { ex with id })
Expand All @@ -179,37 +175,37 @@ module File = struct
* } *)
let max_score =
let key = "max_score.txt" in
{ key ; ciphered = false ;
{ key ;
decode = (fun v -> int_of_string v) ; encode = (fun v -> string_of_int v) ;
field = (fun ex -> ex.max_score);
update = (fun max_score ex -> { ex with max_score });
}
let prelude_ml =
{ key = "prelude.ml" ; ciphered = false ;
{ key = "prelude.ml" ;
decode = (fun v -> v) ; encode = (fun v -> v) ;
field = (fun ex -> ex.prelude_ml) ;
update = (fun prelude_ml ex -> { ex with prelude_ml })
}
let template =
{ key = "template.ml" ; ciphered = false ;
{ key = "template.ml" ;
decode = (fun v -> v) ; encode = (fun v -> v) ;
field = (fun ex -> ex.template) ;
update = (fun template ex -> { ex with template })
}
let solution =
{ key = "solution.ml" ; ciphered = false ;
{ key = "solution.ml" ;
decode = (fun v -> v) ; encode = (fun v -> v) ;
field = (fun ex -> ex.solution) ;
update = (fun solution ex -> { ex with solution })
}
let descr : (string * string) list file =
{ key = "descr.html" ; ciphered = false ;
{ key = "descr.html" ;
decode = descrs_from_string ; encode = descrs_to_string ;
field = (fun ex -> ex.descr) ;
update = (fun descr ex -> { ex with descr })
}
let compiled key get set =
{ key; ciphered = true ;
{ key;
decode = (fun v -> v) ; encode = (fun v -> v) ;
field = (fun ex -> get ex.compiled) ;
update = (fun v ex -> { ex with compiled = set v ex.compiled }) }
Expand Down Expand Up @@ -245,7 +241,7 @@ module File = struct
(fun comp -> comp.test_lib)
(fun test_lib c -> { c with test_lib })
let depend =
{ key = "depend.txt" ; ciphered = false ;
{ key = "depend.txt" ;
decode = (fun v -> Some v) ;
encode = (function
| None -> "" (* no `depend` ~ empty `depend` *)
Expand Down Expand Up @@ -273,7 +269,7 @@ module File = struct
let filenames = parse_dependencies txt in
List.mapi
(fun pos filename ->
{ key = filename ; ciphered = true ;
{ key = filename ;
decode = (fun v -> v) ; encode = (fun v -> v) ;
field = (fun ex -> List.nth ex.dependencies pos) ;
update = (fun v ex ->
Expand All @@ -283,7 +279,7 @@ module File = struct
filenames

module MakeReader (Concur : Concur) = struct
let read ~read_field ?id: ex_id ?(decipher = true) () =
let read ~read_field ?id: ex_id () =
let open Concur in
let ex = ref StringMap.empty in
read_field id.key >>= fun pr_id ->
Expand All @@ -302,18 +298,11 @@ module File = struct
* return (meta_from_string meta_json)
* end >>= fun meta_json ->
* ex := set meta meta_json !ex; *)
let read_file ({ key ; ciphered ; decode ; _ } as field) =
let read_file ({ key ; decode ; _ } as field) =
read_field key >>= function
| Some raw ->
let deciphered =
if ciphered && decipher then
let prefix =
Digest.string (ex_id ^ "_" ^ key) in
Learnocaml_xor.decode ~prefix raw
else
raw in
(* decode / encode now to catch malformed fields earlier *)
ex := set field (decode deciphered) !ex ;
ex := set field (decode raw) !ex ;
return ()
| None -> return () in
(* let read_title () =
Expand Down Expand Up @@ -433,24 +422,14 @@ let access f ex =
let decipher f ex =
let open File in
let raw = f.field ex in
if f.ciphered then
let prefix =
Digest.string (ex.id ^ "_" ^ f.key) in
f.decode (Learnocaml_xor.decode ~prefix raw)
else
f.decode raw
f.decode raw

let update f v ex =
f.File.update v ex

let cipher f v ex =
let open File in
if f.ciphered then
let prefix =
Digest.string (ex.id ^ "_" ^ f.key) in
f.update (Learnocaml_xor.encode ~prefix (f.encode v)) ex
else
f.update (f.encode v) ex
f.update (f.encode v) ex

let field_from_file file files =
try File.(StringMap.find file.key files |> file.decode)
Expand All @@ -471,9 +450,9 @@ module MakeReaderAnddWriter (Concur : Concur) = struct

module FileReader = File.MakeReader(Concur)

let read ~read_field ?id ?decipher () =
let read ~read_field ?id () =
let open Concur in
FileReader.read ~read_field ?id ?decipher () >>= fun ex ->
FileReader.read ~read_field ?id () >>= fun ex ->
try
let depend = File.get_opt File.depend ex in
return
Expand Down Expand Up @@ -507,25 +486,18 @@ module MakeReaderAnddWriter (Concur : Concur) = struct
^ File.(key depend) ^ ", but not found" in
raise (File.Missing_file msg')
in
List.map field_from_dependency (File.dependencies depend)
List.map field_from_dependency (File.dependencies depend)
}
with File.Missing_file _ as e -> fail e

let write ~write_field ex ?(cipher = true) acc =
let write ~write_field ex acc =
let open Concur in
let open File in
let acc = ref acc in
let ex_id = ex.id in
let write_field { key ; ciphered ; encode ; field ; _ } =
let write_field { key ; encode ; field ; _ } =
try
let raw = field ex |> encode in
let ciphered = if ciphered && (not cipher) then
let prefix =
Digest.string (ex_id ^ "_" ^ key) in
Learnocaml_xor.decode ~prefix raw
else
raw in
write_field key ciphered !acc >>= fun nacc ->
write_field key raw !acc >>= fun nacc ->
acc := nacc ;
return ()
with Not_found -> Concur.return () in
Expand Down
11 changes: 5 additions & 6 deletions src/repo/learnocaml_exercise.mli
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ type id = string

type compiled_lib = { cma: string; js: string }

(* JSON encoding of the exercise representation. Includes cipher and decipher at
at encoding and decoding. *)
(* JSON encoding of the exercise representation. *)
val encoding: t Json_encoding.encoding

(** Intermediate representation of files, resulting of reading the exercise directory *)
Expand Down Expand Up @@ -118,25 +117,25 @@ val strip: bool -> t -> t
(** Reader and decipherer *)
val read:
read_field:(string -> string option) ->
?id:string -> ?decipher:bool -> unit ->
?id:string -> unit ->
t

(** Writer and cipherer, ['a] can be [unit] *)
val write:
write_field:(string -> string -> 'a -> 'a) ->
t -> ?cipher:bool -> 'a ->
t -> 'a ->
'a

(** Reader and decipherer with {!Lwt} *)
val read_lwt:
read_field:(string -> string option Lwt.t) ->
?id:string -> ?decipher:bool -> unit ->
?id:string -> unit ->
t Lwt.t

(** Writer and cipherer with {!Lwt}, ['a] can be [unit] *)
val write_lwt:
write_field:(string -> string -> 'a -> 'a Lwt.t) ->
t -> ?cipher:bool -> 'a ->
t -> 'a ->
'a Lwt.t

(** JSON serializer, with {!id} file included *)
Expand Down
2 changes: 1 addition & 1 deletion src/repo/learnocaml_precompile_exercise.ml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ let ocamlc ?(dir=Sys.getcwd ()) ?(opn=[]) ~source ~target args =
let jsoo ?(dir=Sys.getcwd ()) ~source ~target args =
let d = Filename.concat dir in
if is_fresh ~dir target [source] then Lwt.return_unit else
let args = "--wrap-with=dynload" :: "--pretty" :: args in
let args = "--wrap-with=dynload" :: args in
let args = args @ [d source; "-o"; d target] in
run "js_of_ocaml" args

Expand Down
2 changes: 1 addition & 1 deletion src/repo/learnocaml_process_exercise_repository.ml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ let read_exercise exercise_dir =
in
Learnocaml_exercise.read_lwt ~read_field
~id:(Filename.basename exercise_dir)
~decipher:false ()
()

let exercises_dir = ref "./exercises"

Expand Down
8 changes: 0 additions & 8 deletions src/utils/dune
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,6 @@
(modules Lwt_utils)
)

(library
(name learnocaml_xor)
(wrapped false)
(flags :standard -warn-error A-4-42-44-45-48)
(libraries base64)
(modules Learnocaml_xor)
)

(library
(name sha)
(wrapped false)
Expand Down
45 changes: 0 additions & 45 deletions src/utils/learnocaml_xor.ml

This file was deleted.

12 changes: 0 additions & 12 deletions src/utils/learnocaml_xor.mli

This file was deleted.

0 comments on commit 2792faf

Please sign in to comment.