diff --git a/src/packager/packager.re b/src/packager/packager.re index 86fc82f..8055a45 100644 --- a/src/packager/packager.re +++ b/src/packager/packager.re @@ -1,145 +1,56 @@ -/** - * How this works? - * 1. Build a dependencies list of the current package in the correct loading order - * ocamlfind query PACKAGE_NAME -r -p-format -predicates byte - * 2. With that list of all packages. We can find cmi and cma files and building them one by one - * ocamlfind query PACKAGE_NAME -i-format -predicates byte - * ocamlfind query PACKAGE_NAME -a-format -predicates byte - * 3. There are some deduplication going on so we don't build the package twice - */ -open Utils; -let verbose = ref(false); -let output = ref(None); - -let execute = execute(~verbose); - -let usage = () => { - Format.eprintf("Usage: sketch [find packages] @."); - Format.eprintf(" --verbose@."); - Format.eprintf(" --output\t\t\tBuild output directory@."); - Format.eprintf(" --help\t\t\tDisplay usage@."); - exit(1); +let verbose = ref(true); +let exec = Utils.execute(~verbose); + +module Ocamlfind = { + let cmas = name => + ["ocamlfind query", name, "-r -predicates byte -a-format"] |> exec; + let cmis = name => + ["ocamlfind query", name, "-r -predicates byte -i-format"] |> exec; }; -let rec scan_args = acc => - fun - | ["--verbose", ...xs] => { - verbose := true; - scan_args(acc, xs); - } - | ["--help" | "-h", ..._] => usage() - | ["--output", outputDir, ...xs] => { - output := Some(outputDir); - scan_args(acc, xs); - } - | [x, ...xs] => scan_args([x, ...acc], xs) - | [] => List.rev(acc); +module Ocamlc = { + let archive = (aFiles, output) => { + let cma = output ++ ".cma"; + ["ocamlc -a", aFiles, "-o", cma] |> exec |> ignore; + cma; + }; +}; -let findDeps = name => - execute([ - "ocamlfind", - "query", - name, - "-r", - "-p-format", - "-predicates byte", - ]); -let findCmi = name => - execute(["ocamlfind", "query", name, "-i-format", "-predicates byte"]); -let findCma = name => - execute(["ocamlfind", "query", name, "-a-format", "-predicates byte"]); +module Jsoo = { + let lib = name => name ++ ".sketch.lib.js"; -let buildLib = (~outputDir, packageName) => { - if (verbose^) { - Printf.printf("Building library with jsoo: %s\n", packageName); - }; - let safePkgName = toSafePackageName(packageName); - let funcName = "sketch__private__" ++ safePkgName; + let autoBootstrap = libName => + ["echo \"sketch_private__" ++ libName ++ "(self);\"", ">>", lib(libName)] + |> exec + |> ignore; - let cmaPath = findCma(packageName); - switch (String.trim(cmaPath)) { - | "" => print_endline("Can't find cma file for package " ++ packageName) - | _ => - execute([ + let compile = (libName, archive, cmis) => + [ "js_of_ocaml", - "--wrap-with-fun=" ++ funcName, + "--wrap-with-fun=sketch_private__" ++ libName, "--toplevel", - findCmi(packageName), - findCma(packageName), + cmis, + archive, "-o", - Filename.concat(outputDir, safePkgName ++ ".lib.sketch.js"), - ]) - |> ignore - }; + lib(libName), + ] + |> exec + |> ignore; }; -module SS = Set.Make(String); -module LibMap = Map.Make(String); - -/* - * These packages are for compatibility with OCaml - * But Sketch only supports OCaml > 4.06 - * So this will result in not found packages - */ - -let excludedPackages = SS.of_list(["uchar", "result", "bytes"]); +module Cli = { + let run = () => { + let libName = Sys.argv[1]; + Printf.printf("Beginning build for \"%s\"...\n", libName); -module J = Json; + let cmas = Ocamlfind.cmas(libName); + let cmis = Ocamlfind.cmis(libName); + let bundle = Ocamlc.archive(cmas, libName); + Jsoo.compile(libName, bundle, cmis); + Jsoo.autoBootstrap(libName); -let build = (~outputDir, toplevelPkgs) => { - /* if (verbose^) { - Printf.printf("Building dependencies for: %s\n", toplevelPkg); - }; */ - let libsToBuild = ref(SS.empty); - let libsWithDependencies = - toplevelPkgs - |> List.fold_left( - (map: LibMap.t(list(string)), pkg) => { - let allDeps = - findDeps(pkg) - |> String.split_on_char('\n') - |> List.filter(name => name != "") - |> List.filter(name => !SS.mem(name, excludedPackages)); - - let _ = - allDeps - |> List.iter(name => libsToBuild := libsToBuild^ |> SS.add(name)); - - map |> LibMap.add(pkg, allDeps); - }, - LibMap.empty, - ); - - let _ = libsToBuild^ |> SS.iter(name => buildLib(~outputDir, name)); - let _ = - LibMap.fold( - (topName, libs, acc) => { - let libField = - J.Object([ - (topName, J.Array(libs |> List.map(name => J.String(name)))), - ]); - [libField, ...acc]; - }, - libsWithDependencies, - [], - ) - |> (list => J.Array(list)) - |> (json => J.stringify(json)) - |> writeFileSync(~path=Filename.concat(outputDir, "list.json")); - (); + Printf.printf("📦 Done!\n"); + }; }; -let _ = { - let args = List.tl(Array.to_list(Sys.argv)); - let args = scan_args([], args); - - let outputDir = - switch (output^) { - | None => Filename.concat(Sys.getcwd(), "packages") - | Some(output) => output - }; - mkdirp(outputDir); - - build(~outputDir, args); - print_endline("Done !"); -}; +Cli.run();