├── .gitignore ├── .travis.yml ├── Makefile ├── README.md ├── bin ├── dune └── main.re ├── dune-project ├── esy.lock.json ├── lib.md ├── package.json ├── rrun.opam ├── rrundep ├── dune └── rrundep.re └── rrunlib ├── BuildSystem.re ├── BuildSystem.rei ├── Cmd.re ├── Cmd.rei ├── Config.re ├── Config.rei ├── DepsMeta.re ├── DepsMeta.rei ├── Fs.re ├── Fs.rei ├── Path.re ├── Process.re ├── Process.rei ├── Source.re ├── Source.rei ├── System.re ├── System.rei └── dune /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | *.install 3 | .merlin 4 | _build 5 | _release 6 | test 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | os: 3 | - linux 4 | - osx 5 | node_js: 6 | - '8' 7 | install: 8 | - npm install -g esy@0.2.4 9 | - esy install 10 | script: 11 | - esy build 12 | - esy release 13 | cache: 14 | timeout: 360 15 | directories: 16 | - "$HOME/.esy/" 17 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | default:: 2 | @esy install 3 | @esy build 4 | 5 | b build:: 6 | @esy b dune build 7 | 8 | fmt: 9 | @find bin rrundep rrunlib -name '*.ml' -or -name '*.mli' \ 10 | | xargs -n1 esy ocamlformat --inplace 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rrun 2 | 3 | **WIP: DO NOT USE, this piece of software isn't ready for general consumption, 4 | some things are not implemented, some things are not working properly.** 5 | 6 | [![Build Status](https://travis-ci.com/andreypopp/rrun.svg?branch=master)](https://travis-ci.com/andreypopp/rrun) 7 | 8 | rrun allows to seamlessly run [Reason][]/[OCaml][] code with native speed. 9 | 10 | ## Motivation 11 | 12 | rrun aims to implement the following workflow for engineering software with 13 | Reason/OCaml language: 14 | 15 | - Start writing code by opening a plain `*.re` or `*.ml` file 16 | - ... with autocomplete and real time error reporting available 17 | - ... having a good set of standard libraries for interacting with a system 18 | - ... reusing 3rd party code from a local file system or from the network 19 | - Code can be run with a single command invocation `rrun ./myapp.re` 20 | - ... which builds the code and caches the result 21 | - ... and sandboxes (configurable) execution by preventing it from 22 | reading/writing to disk or accessing network 23 | 24 | ## Installation (not implemented yet) 25 | 26 | Install rrun via npm: 27 | 28 | ```shell 29 | % npm install -g rrun 30 | ``` 31 | 32 | ## Usage 33 | 34 | ### Running Code 35 | 36 | Run Reason/OCaml code with: 37 | 38 | ```shell 39 | % rrun ./app.re 40 | % rrun ./app.ml 41 | ``` 42 | 43 | rrun uses `ocamlopt` to compile sources and then caches compiled artifacts, on 44 | second invocation there will be no recompilation. 45 | 46 | ### Dependencies 47 | 48 | You can specify dependencies between modules with `[%import "..."]` syntax: 49 | 50 | ``` 51 | module Url = [%import "./Url.re"] 52 | module Chalk = [%import "https://example.com/Chalk.re"] 53 | 54 | let url = Url.make("http://example.com"); 55 | print_endline(Chalk.red(Url.show(url))); 56 | ``` 57 | 58 | ### IDE support 59 | 60 | There's `rrun edit` command which will run your configured editor (via 61 | `$EDITOR`) in a properly configured environment: 62 | 63 | ``` 64 | % rrun edit ./app.re 65 | ``` 66 | 67 | ### Sandboxed Execution 68 | 69 | TODO 70 | 71 | ## Internals 72 | 73 | TODO 74 | 75 | ## Development 76 | 77 | ### Workflow 78 | 79 | ``` 80 | % npm install -g esy 81 | % git clone https://github.com/andreypopp/rrun.git 82 | % cd rrun 83 | % esy install 84 | % esy build 85 | % esy "$EDITOR" 86 | ``` 87 | 88 | ### Roadmap 89 | 90 | - [ ] Sandboxed execution 91 | - [ ] Support interfaces 92 | 93 | - [x] Build Reason code 94 | - [x] Build OCaml code 95 | - [x] Support `[%import "./relative/path.ml"]` dependencies 96 | - [x] Support `[%import "https://secure/url.ml"]` dependencies 97 | 98 | [OCaml]: https://ocaml.org 99 | [Reason]: https://reasonml.github.io 100 | -------------------------------------------------------------------------------- /bin/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name main) 3 | (public_name rrun) 4 | (preprocess (pps lwt_ppx)) 5 | (libraries rrun lwt lwt.unix cmdliner fpath)) 6 | -------------------------------------------------------------------------------- /bin/main.re: -------------------------------------------------------------------------------- 1 | open Rrun; 2 | 3 | module Api = { 4 | let build = (cfg, path) => { 5 | let comp = { 6 | let%lwt outFilename = Rrun.BuildSystem.build(~cfg, path); 7 | Lwt.return(outFilename); 8 | }; 9 | 10 | let _ = Lwt_main.run(comp); 11 | `Ok(); 12 | }; 13 | 14 | let default = (cfg, path) => { 15 | let comp = { 16 | let%lwt outFilename = Rrun.BuildSystem.build(~cfg, path); 17 | Lwt.return(outFilename); 18 | }; 19 | 20 | let exePath = Lwt_main.run(comp); 21 | Unix.execv(Fpath.to_string(exePath), Sys.argv); 22 | }; 23 | 24 | let merlin = cfg => 25 | Format.asprintf( 26 | {| 27 | B %a 28 | S %a 29 | FLG -ppx 'rrundep --as-ppx' 30 | FLG -w @a-4-29-40-41-42-44-45-48-58-59-60-40 -strict-sequence -strict-formats -short-paths -keep-locs 31 | |}, 32 | Fpath.pp, 33 | cfg.Config.store_path, 34 | Fpath.pp, 35 | cfg.Config.store_path, 36 | ); 37 | 38 | let generate_merlin = cfg => { 39 | print_endline(merlin(cfg)); 40 | `Ok(); 41 | }; 42 | 43 | let edit = (cfg, path) => { 44 | let editor = 45 | try (Sys.getenv("EDITOR")) { 46 | | Not_found => "vi" 47 | }; 48 | let parent = Fpath.(parent(path) / ".merlin"); 49 | let oc = open_out(Fpath.to_string(parent)); 50 | output_string(oc, merlin(cfg)); 51 | close_out(oc); 52 | Unix.execv(editor, [|editor, Fpath.to_string(path)|]); 53 | }; 54 | }; 55 | 56 | open Cmdliner; 57 | 58 | let path = { 59 | let parse = Fpath.of_string; 60 | let print = Fpath.pp; 61 | Arg.conv(~docv="PATH", (parse, print)); 62 | }; 63 | 64 | let program_arg = { 65 | let doc = "Program"; 66 | Arg.( 67 | required & pos(0, some(path), None) & info([], ~docv="PROGRAM", ~doc) 68 | ); 69 | }; 70 | 71 | let config_arg = { 72 | let init_config = () => Lwt_main.run(Config.init()); 73 | 74 | Term.(const(init_config) $ const()); 75 | }; 76 | 77 | let default_cmd = { 78 | let doc = "Run program."; 79 | let sdocs = Manpage.s_common_options; 80 | let exits = Term.default_exits; 81 | let info = Term.info("rrun", ~doc, ~sdocs, ~exits); 82 | (Term.(ret(const(Api.default) $ config_arg $ program_arg)), info); 83 | }; 84 | 85 | let build_cmd = { 86 | let doc = "Build program."; 87 | let sdocs = Manpage.s_common_options; 88 | let exits = Term.default_exits; 89 | let info = Term.info("build", ~doc, ~sdocs, ~exits); 90 | (Term.(ret(const(Api.build) $ config_arg $ program_arg)), info); 91 | }; 92 | 93 | let run_cmd = { 94 | let doc = "Build and run program."; 95 | let sdocs = Manpage.s_common_options; 96 | let exits = Term.default_exits; 97 | let info = Term.info("run", ~doc, ~sdocs, ~exits); 98 | (Term.(ret(const(Api.default) $ config_arg $ program_arg)), info); 99 | }; 100 | 101 | let merlin_cmd = { 102 | let doc = "Generate .merlin file."; 103 | let sdocs = Manpage.s_common_options; 104 | let exits = Term.default_exits; 105 | let info = Term.info("gen-merlin", ~doc, ~sdocs, ~exits); 106 | (Term.(ret(const(Api.generate_merlin) $ config_arg)), info); 107 | }; 108 | 109 | let edit_cmd = { 110 | let doc = "Edit program."; 111 | let sdocs = Manpage.s_common_options; 112 | let exits = Term.default_exits; 113 | let info = Term.info("edit", ~doc, ~sdocs, ~exits); 114 | (Term.(ret(const(Api.edit) $ config_arg $ program_arg)), info); 115 | }; 116 | 117 | let cmds = [run_cmd, build_cmd, merlin_cmd, edit_cmd]; 118 | 119 | let () = { 120 | Printexc.record_backtrace(true); 121 | /* fixup args so we can use default invocation for run */ 122 | let argv = 123 | switch (Sys.argv[1]) { 124 | | exception (Invalid_argument(_)) => Sys.argv 125 | | "" 126 | | "build" 127 | | "run" 128 | | "gen-merlin" 129 | | "edit" 130 | | "--" => Sys.argv 131 | | w => 132 | if (w.[0] == '-') { 133 | Sys.argv; 134 | } else { 135 | let argv = Array.make(Array.length(Sys.argv) + 1, ""); 136 | argv[0] = Sys.argv[0]; 137 | argv[1] = "--"; 138 | let copy_arg = (i, v) => 139 | if (i >= 1) { 140 | argv[i + 1] = v; 141 | } else { 142 | (); 143 | }; 144 | Array.iteri(copy_arg, Sys.argv); 145 | argv; 146 | } 147 | }; 148 | 149 | Term.(exit @@ eval_choice(~argv, default_cmd, cmds)); 150 | }; 151 | -------------------------------------------------------------------------------- /dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 1.0) 2 | -------------------------------------------------------------------------------- /esy.lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "hash": "1292edc764753d3a28c8aa1183775957", 3 | "root": "rrun@path:.", 4 | "node": { 5 | "rrun@path:.": { 6 | "record": { 7 | "name": "rrun", 8 | "version": "path:.", 9 | "source": "path:.", 10 | "files": [], 11 | "opam": null 12 | }, 13 | "dependencies": [ 14 | "@esy-ocaml/reason@3.3.0", "@opam/cmdliner@opam:1.0.2", 15 | "@opam/dune@opam:1.0.1", "@opam/fmt@opam:0.8.5", 16 | "@opam/fpath@opam:0.7.2", "@opam/lwt@opam:4.1.0", 17 | "@opam/lwt_ppx@opam:1.2.1", "@opam/merlin@opam:3.1.0", 18 | "@opam/ocamlformat@opam:0.6", "@opam/ppx_compare@opam:v0.11.1", 19 | "@opam/ppx_let@opam:v0.11.0", "@opam/ppx_sexp_conv@opam:v0.11.2", 20 | "@opam/ppxlib@opam:0.3.0", "@opam/sexplib@opam:v0.11.0", 21 | "@opam/uri@opam:1.9.7", "ocaml@4.6.4" 22 | ] 23 | }, 24 | "ocaml@4.6.4": { 25 | "record": { 26 | "name": "ocaml", 27 | "version": "4.6.4", 28 | "source": 29 | "archive:https://registry.npmjs.org/ocaml/-/ocaml-4.6.4.tgz#sha1:315bc4f8231b605674306715ce362dfaf42fee2c", 30 | "files": [], 31 | "opam": null 32 | }, 33 | "dependencies": [] 34 | }, 35 | "@opam/yojson@opam:1.4.1": { 36 | "record": { 37 | "name": "@opam/yojson", 38 | "version": "opam:1.4.1", 39 | "source": [ 40 | "archive:https://opam.ocaml.org/archives/yojson.1.4.1+opam.tar.gz#md5:e6c9643ee76e622ca2e53ef9e4091192", 41 | "archive:https://github.com/mjambon/yojson/archive/v1.4.1.tar.gz#md5:3ea6e36422dd670e8ab880710d5f7398" 42 | ], 43 | "files": [], 44 | "opam": { 45 | "name": "yojson", 46 | "version": "1.4.1", 47 | "opam": 48 | "opam-version: \"1.2\"\nmaintainer: \"martin@mjambon.com\"\nauthors: \"Martin Jambon\"\nhomepage: \"http://mjambon.com/yojson.html\"\nbug-reports: \"https://github.com/mjambon/yojson/issues\"\ndepends: [\n \"jbuilder\" {build}\n \"cppo\" {build}\n \"easy-format\"\n \"biniou\" {>= \"1.2.0\"}\n]\navailable: ocaml-version >= \"4.02.3\"\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\nrun-test: [\"jbuilder\" \"runtest\" \"-p\" name]\ndev-repo: \"git+https://github.com/mjambon/yojson.git\"", 49 | "override": null 50 | } 51 | }, 52 | "dependencies": [ 53 | "@esy-ocaml/substs@0.0.1", "@opam/biniou@opam:1.2.0", 54 | "@opam/cppo@opam:1.6.4", "@opam/easy-format@opam:1.3.1", 55 | "@opam/jbuilder@opam:transition" 56 | ] 57 | }, 58 | "@opam/uri@opam:1.9.7": { 59 | "record": { 60 | "name": "@opam/uri", 61 | "version": "opam:1.9.7", 62 | "source": [ 63 | "archive:https://opam.ocaml.org/archives/uri.1.9.7+opam.tar.gz#md5:b05936ab09a23ccd111efaf8cce4950f", 64 | "archive:https://github.com/mirage/ocaml-uri/releases/download/v1.9.7/uri-1.9.7.tbz#md5:2fb8da55f99a529bcb211a1d99822419" 65 | ], 66 | "files": [], 67 | "opam": { 68 | "name": "uri", 69 | "version": "1.9.7", 70 | "opam": 71 | "opam-version: \"1.2\"\nmaintainer: \"sheets@alum.mit.edu\"\nauthors: [\"Anil Madhavapeddy\" \"David Sheets\" \"Rudi Grinberg\"]\nlicense: \"ISC\"\ntags: [\"url\" \"uri\" \"org:mirage\" \"org:xapi-project\"]\nhomepage: \"https://github.com/mirage/ocaml-uri\"\nbug-reports: \"https://github.com/mirage/ocaml-uri/issues\"\ndepends: [\n \"jbuilder\" {build & >= \"1.0+beta7\"}\n \"ounit\" {test & >= \"1.0.2\"}\n \"ppx_sexp_conv\" {>= \"v0.9.0\"}\n \"re\" {>= \"1.7.2\"}\n \"sexplib\" {>= \"v0.9.0\"}\n \"stringext\" {>= \"1.4.0\"}\n]\navailable: ocaml-version >= \"4.03.0\"\nbuild: [\n [\"jbuilder\" \"subst\" \"-p\" name] {pinned}\n [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\n]\nrun-test: [\"jbuilder\" \"runtest\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git+https://github.com/mirage/ocaml-uri.git\"", 72 | "override": null 73 | } 74 | }, 75 | "dependencies": [ 76 | "@esy-ocaml/substs@0.0.1", "@opam/jbuilder@opam:transition", 77 | "@opam/ppx_sexp_conv@opam:v0.11.2", "@opam/re@opam:1.7.3", 78 | "@opam/sexplib@opam:v0.11.0", "@opam/stringext@opam:1.5.0" 79 | ] 80 | }, 81 | "@opam/uchar@opam:0.0.2": { 82 | "record": { 83 | "name": "@opam/uchar", 84 | "version": "opam:0.0.2", 85 | "source": [ 86 | "archive:https://opam.ocaml.org/archives/uchar.0.0.2+opam.tar.gz#md5:a4754e44371178a883821e664f644b19", 87 | "archive:https://github.com/ocaml/uchar/releases/download/v0.0.2/uchar-0.0.2.tbz#md5:c9ba2c738d264c420c642f7bb1cf4a36" 88 | ], 89 | "files": [], 90 | "opam": { 91 | "name": "uchar", 92 | "version": "0.0.2", 93 | "opam": 94 | "opam-version: \"1.2\"\nmaintainer: \"Daniel Bünzli \"\nauthors: \"Daniel Bünzli \"\nlicense: \"typeof OCaml system\"\ntags: [\"text\" \"character\" \"unicode\" \"compatibility\" \"org:ocaml.org\"]\nhomepage: \"http://ocaml.org\"\ndoc: \"https://ocaml.github.io/uchar/\"\nbug-reports: \"https://github.com/ocaml/uchar/issues\"\ndepends: [\n \"ocamlbuild\" {build}\n]\navailable: ocaml-version >= \"3.12.0\"\nbuild: [\n [\"ocaml\" \"pkg/git.ml\"]\n [\n \"ocaml\"\n \"pkg/build.ml\"\n \"native=%{ocaml-native}%\"\n \"native-dynlink=%{ocaml-native-dynlink}%\"\n ]\n]\ndev-repo: \"git+https://github.com/ocaml/uchar.git\"", 95 | "override": null 96 | } 97 | }, 98 | "dependencies": [ 99 | "@esy-ocaml/substs@0.0.1", "@opam/ocamlbuild@opam:0.12.0" 100 | ] 101 | }, 102 | "@opam/topkg@opam:0.9.1": { 103 | "record": { 104 | "name": "@opam/topkg", 105 | "version": "opam:0.9.1", 106 | "source": [ 107 | "archive:https://opam.ocaml.org/archives/topkg.0.9.1+opam.tar.gz#md5:1ec2522f346d19bf4c24c3c0b2e3e8bd", 108 | "archive:http://erratique.ch/software/topkg/releases/topkg-0.9.1.tbz#md5:8978a0595db1a22e4251ec62735d4b84" 109 | ], 110 | "files": [], 111 | "opam": { 112 | "name": "topkg", 113 | "version": "0.9.1", 114 | "opam": 115 | "opam-version: \"1.2\"\nmaintainer: \"Daniel Bünzli \"\nauthors: \"Daniel Bünzli \"\nlicense: \"ISC\"\ntags: [\"packaging\" \"ocamlbuild\" \"org:erratique\"]\nhomepage: \"http://erratique.ch/software/topkg\"\ndoc: \"http://erratique.ch/software/topkg/doc\"\nbug-reports: \"https://github.com/dbuenzli/topkg/issues\"\ndepends: [\n \"ocamlfind\" {build & >= \"1.6.1\"}\n \"ocamlbuild\"\n \"result\"\n]\navailable: ocaml-version >= \"4.01.0\"\nbuild: [\n \"ocaml\" \"pkg/pkg.ml\" \"build\" \"--pkg-name\" name \"--dev-pkg\" \"%{pinned}%\"\n]\ndev-repo: \"git+http://erratique.ch/repos/topkg.git\"", 116 | "override": null 117 | } 118 | }, 119 | "dependencies": [ 120 | "@esy-ocaml/substs@0.0.1", "@opam/ocamlbuild@opam:0.12.0", 121 | "@opam/ocamlfind@opam:1.8.0", "@opam/result@opam:1.3" 122 | ] 123 | }, 124 | "@opam/stringext@opam:1.5.0": { 125 | "record": { 126 | "name": "@opam/stringext", 127 | "version": "opam:1.5.0", 128 | "source": [ 129 | "archive:https://opam.ocaml.org/archives/stringext.1.5.0+opam.tar.gz#md5:2d0810a928ebd057a122776cced58208", 130 | "archive:https://github.com/rgrinberg/stringext/archive/1.5.0.zip#md5:867263ea97532f150516677fa994cdf2" 131 | ], 132 | "files": [], 133 | "opam": { 134 | "name": "stringext", 135 | "version": "1.5.0", 136 | "opam": 137 | "opam-version: \"1.2\"\nmaintainer: \"rudi.grinberg@gmail.com\"\nauthors: \"Rudi Grinberg\"\nlicense: \"MIT\"\nhomepage: \"https://github.com/rgrinberg/stringext\"\nbug-reports: \"https://github.com/rgrinberg/stringext/issues\"\ndepends: [\n \"jbuilder\" {build & >= \"1.0+beta10\"}\n \"ounit\" {test}\n \"qtest\" {test & >= \"2.2\"}\n \"base-bytes\"\n]\navailable: ocaml-version >= \"4.02.3\"\nbuild: [\n [\"jbuilder\" \"subst\" \"-p\" name] {pinned}\n [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\n]\nrun-test: [\"jbuilder\" \"runtest\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git+https://github.com/rgrinberg/stringext.git\"", 138 | "override": null 139 | } 140 | }, 141 | "dependencies": [ 142 | "@esy-ocaml/substs@0.0.1", "@opam/base-bytes@opam:base", 143 | "@opam/jbuilder@opam:transition" 144 | ] 145 | }, 146 | "@opam/stdio@opam:v0.11.0": { 147 | "record": { 148 | "name": "@opam/stdio", 149 | "version": "opam:v0.11.0", 150 | "source": [ 151 | "archive:https://opam.ocaml.org/archives/stdio.v0.11.0+opam.tar.gz#md5:bfc3df3658e4f5cd847fc7e2fa867e8b", 152 | "archive:https://ocaml.janestreet.com/ocaml-core/v0.11/files/stdio-v0.11.0.tar.gz#md5:2db42ee38c91b3ff7126c2634c407b99" 153 | ], 154 | "files": [], 155 | "opam": { 156 | "name": "stdio", 157 | "version": "v0.11.0", 158 | "opam": 159 | "opam-version: \"1.2\"\nmaintainer: \"opensource@janestreet.com\"\nauthors: \"Jane Street Group, LLC \"\nlicense: \"Apache-2.0\"\nhomepage: \"https://github.com/janestreet/stdio\"\nbug-reports: \"https://github.com/janestreet/stdio/issues\"\ndepends: [\n \"base\" {>= \"v0.11\" & < \"v0.12\"}\n \"jbuilder\" {build & >= \"1.0+beta18.1\"}\n]\navailable: ocaml-version >= \"4.04.1\"\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git+https://github.com/janestreet/stdio.git\"", 160 | "override": null 161 | } 162 | }, 163 | "dependencies": [ 164 | "@esy-ocaml/substs@0.0.1", "@opam/base@opam:v0.11.1", 165 | "@opam/jbuilder@opam:transition" 166 | ] 167 | }, 168 | "@opam/sexplib0@opam:v0.11.0": { 169 | "record": { 170 | "name": "@opam/sexplib0", 171 | "version": "opam:v0.11.0", 172 | "source": [ 173 | "archive:https://opam.ocaml.org/archives/sexplib0.v0.11.0+opam.tar.gz#md5:bc98d0dae9b81c0d1709fd529d813cb3", 174 | "archive:https://ocaml.janestreet.com/ocaml-core/v0.11/files/sexplib0-v0.11.0.tar.gz#md5:1c14ba30b471e49f1b23fea5ff99ea6b" 175 | ], 176 | "files": [], 177 | "opam": { 178 | "name": "sexplib0", 179 | "version": "v0.11.0", 180 | "opam": 181 | "opam-version: \"1.2\"\nmaintainer: \"opensource@janestreet.com\"\nauthors: \"Jane Street Group, LLC \"\nlicense: \"Apache-2.0\"\nhomepage: \"https://github.com/janestreet/sexplib0\"\nbug-reports: \"https://github.com/janestreet/sexplib0/issues\"\ndepends: [\n \"jbuilder\" {build & >= \"1.0+beta18.1\"}\n]\nconflicts: [\n \"sexplib\" {< \"v0.11\"}\n]\navailable: ocaml-version >= \"4.04.1\"\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git+https://github.com/janestreet/sexplib0.git\"", 182 | "override": null 183 | } 184 | }, 185 | "dependencies": [ 186 | "@esy-ocaml/substs@0.0.1", "@opam/jbuilder@opam:transition" 187 | ] 188 | }, 189 | "@opam/sexplib@opam:v0.11.0": { 190 | "record": { 191 | "name": "@opam/sexplib", 192 | "version": "opam:v0.11.0", 193 | "source": [ 194 | "archive:https://opam.ocaml.org/archives/sexplib.v0.11.0+opam.tar.gz#md5:6c476dc8e7dfe15f32785d185f6e3466", 195 | "archive:https://ocaml.janestreet.com/ocaml-core/v0.11/files/sexplib-v0.11.0.tar.gz#md5:1d53d945914b6b9a380dc8923f19e9ae" 196 | ], 197 | "files": [], 198 | "opam": { 199 | "name": "sexplib", 200 | "version": "v0.11.0", 201 | "opam": 202 | "opam-version: \"1.2\"\nmaintainer: \"opensource@janestreet.com\"\nauthors: \"Jane Street Group, LLC \"\nlicense: \"Apache-2.0\"\nhomepage: \"https://github.com/janestreet/sexplib\"\nbug-reports: \"https://github.com/janestreet/sexplib/issues\"\ndepends: [\n \"parsexp\" {>= \"v0.11\" & < \"v0.12\"}\n \"sexplib0\" {>= \"v0.11\" & < \"v0.12\"}\n \"jbuilder\" {build & >= \"1.0+beta18.1\"}\n \"num\"\n]\navailable: ocaml-version >= \"4.04.1\"\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git+https://github.com/janestreet/sexplib.git\"", 203 | "override": null 204 | } 205 | }, 206 | "dependencies": [ 207 | "@esy-ocaml/substs@0.0.1", "@opam/jbuilder@opam:transition", 208 | "@opam/num@opam:1.1", "@opam/parsexp@opam:v0.11.0", 209 | "@opam/sexplib0@opam:v0.11.0" 210 | ] 211 | }, 212 | "@opam/result@opam:1.3": { 213 | "record": { 214 | "name": "@opam/result", 215 | "version": "opam:1.3", 216 | "source": [ 217 | "archive:https://opam.ocaml.org/archives/result.1.3+opam.tar.gz#md5:627b5fd1f70949a36e38cb2798021f9a", 218 | "archive:https://github.com/janestreet/result/releases/download/1.3/result-1.3.tbz#md5:4beebefd41f7f899b6eeba7414e7ae01" 219 | ], 220 | "files": [], 221 | "opam": { 222 | "name": "result", 223 | "version": "1.3", 224 | "opam": 225 | "opam-version: \"1.2\"\nmaintainer: \"opensource@janestreet.com\"\nauthors: \"Jane Street Group, LLC \"\nlicense: \"BSD3\"\nhomepage: \"https://github.com/janestreet/result\"\nbug-reports: \"https://github.com/janestreet/result/issues\"\ndepends: [\n \"jbuilder\" {build & >= \"1.0+beta11\"}\n]\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git+https://github.com/janestreet/result.git\"", 226 | "override": null 227 | } 228 | }, 229 | "dependencies": [ 230 | "@esy-ocaml/substs@0.0.1", "@opam/jbuilder@opam:transition" 231 | ] 232 | }, 233 | "@opam/re@opam:1.7.3": { 234 | "record": { 235 | "name": "@opam/re", 236 | "version": "opam:1.7.3", 237 | "source": [ 238 | "archive:https://opam.ocaml.org/archives/re.1.7.3+opam.tar.gz#md5:065e5d37c2892bf184505f416e072bec", 239 | "archive:https://github.com/ocaml/ocaml-re/releases/download/1.7.3/re-1.7.3.tbz#md5:d2a74ca77216861bce4449600a132de9" 240 | ], 241 | "files": [], 242 | "opam": { 243 | "name": "re", 244 | "version": "1.7.3", 245 | "opam": 246 | "opam-version: \"1.2\"\nmaintainer: \"rudi.grinberg@gmail.com\"\nauthors: [\n \"Jerome Vouillon\"\n \"Thomas Gazagnaire\"\n \"Anil Madhavapeddy\"\n \"Rudi Grinberg\"\n \"Gabriel Radanne\"\n]\nlicense: \"LGPL-2.0 with OCaml linking exception\"\nhomepage: \"https://github.com/ocaml/ocaml-re\"\nbug-reports: \"https://github.com/ocaml/ocaml-re/issues\"\ndepends: [\n \"jbuilder\" {build & >= \"1.0+beta10\"}\n \"ounit\" {test}\n]\navailable: ocaml-version >= \"4.02.3\"\nbuild: [\n [\"jbuilder\" \"subst\" \"-p\" name] {pinned}\n [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\n]\nrun-test: [\"jbuilder\" \"runtest\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git+https://github.com/ocaml/ocaml-re.git\"", 247 | "override": null 248 | } 249 | }, 250 | "dependencies": [ 251 | "@esy-ocaml/substs@0.0.1", "@opam/jbuilder@opam:transition" 252 | ] 253 | }, 254 | "@opam/ppxlib@opam:0.3.0": { 255 | "record": { 256 | "name": "@opam/ppxlib", 257 | "version": "opam:0.3.0", 258 | "source": [ 259 | "archive:https://opam.ocaml.org/archives/ppxlib.0.3.0+opam.tar.gz#md5:01a1c0c788d392f9b846248803e24051", 260 | "archive:https://github.com/ocaml-ppx/ppxlib/archive/0.3.0.tar.gz#md5:e6ff83b1643a44fcb6b0acde4d2aa299" 261 | ], 262 | "files": [], 263 | "opam": { 264 | "name": "ppxlib", 265 | "version": "0.3.0", 266 | "opam": 267 | "opam-version: \"1.2\"\nmaintainer: \"opensource@janestreet.com\"\nauthors: \"Jane Street Group, LLC \"\nlicense: \"Apache-2.0\"\nhomepage: \"https://github.com/ocaml-ppx/ppxlib\"\nbug-reports: \"https://github.com/ocaml-ppx/ppxlib/issues\"\ndepends: [\n \"base\" {>= \"v0.11.0\"}\n \"dune\" {build}\n \"ocaml-compiler-libs\" {>= \"v0.11.0\"}\n \"ocaml-migrate-parsetree\" {>= \"1.0.9\"}\n \"ppx_derivers\" {>= \"1.0\"}\n \"stdio\" {>= \"v0.11.0\"}\n]\navailable: ocaml-version >= \"4.04.1\"\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git+https://github.com/ocaml-ppx/ppxlib.git\"", 268 | "override": null 269 | } 270 | }, 271 | "dependencies": [ 272 | "@esy-ocaml/substs@0.0.1", "@opam/base@opam:v0.11.1", 273 | "@opam/dune@opam:1.0.1", "@opam/ocaml-compiler-libs@opam:v0.11.0", 274 | "@opam/ocaml-migrate-parsetree@opam:1.0.11", 275 | "@opam/ppx_derivers@opam:1.0", "@opam/stdio@opam:v0.11.0" 276 | ] 277 | }, 278 | "@opam/ppx_tools_versioned@opam:5.2": { 279 | "record": { 280 | "name": "@opam/ppx_tools_versioned", 281 | "version": "opam:5.2", 282 | "source": [ 283 | "archive:https://opam.ocaml.org/archives/ppx_tools_versioned.5.2+opam.tar.gz#md5:8fd1b5ae4a846543df0b1ed6e008cfc8", 284 | "archive:https://github.com/ocaml-ppx/ppx_tools_versioned/archive/5.2.tar.gz#md5:f2f1a1cd11aeb9f91a92ab691720a401" 285 | ], 286 | "files": [], 287 | "opam": { 288 | "name": "ppx_tools_versioned", 289 | "version": "5.2", 290 | "opam": 291 | "opam-version: \"1.2\"\nmaintainer: \"frederic.bour@lakaban.net\"\nauthors: [\n \"Frédéric Bour \"\n \"Alain Frisch \"\n]\nlicense: \"MIT\"\ntags: \"syntax\"\nhomepage: \"https://github.com/let-def/ppx_tools_versioned\"\nbug-reports: \"https://github.com/let-def/ppx_tools_versioned/issues\"\ndepends: [\n \"jbuilder\" {build & >= \"1.0+beta17\"}\n \"ocaml-migrate-parsetree\" {>= \"0.5\"}\n]\navailable: ocaml-version >= \"4.02.0\"\nbuild: [\n [\"jbuilder\" \"subst\" \"-p\" name] {pinned}\n [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\n]\nrun-test: [\"jbuilder\" \"runtest\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git://github.com/let-def/ppx_tools_versioned.git\"", 292 | "override": null 293 | } 294 | }, 295 | "dependencies": [ 296 | "@esy-ocaml/substs@0.0.1", "@opam/jbuilder@opam:transition", 297 | "@opam/ocaml-migrate-parsetree@opam:1.0.11" 298 | ] 299 | }, 300 | "@opam/ppx_sexp_conv@opam:v0.11.2": { 301 | "record": { 302 | "name": "@opam/ppx_sexp_conv", 303 | "version": "opam:v0.11.2", 304 | "source": [ 305 | "archive:https://opam.ocaml.org/archives/ppx_sexp_conv.v0.11.2+opam.tar.gz#md5:db2348b7ed0a541aabe9dc08d4a472ac", 306 | "archive:https://github.com/janestreet/ppx_sexp_conv/archive/v0.11.2.tar.gz#md5:77d3b30b3d9c5810552bde2027656b8d" 307 | ], 308 | "files": [], 309 | "opam": { 310 | "name": "ppx_sexp_conv", 311 | "version": "v0.11.2", 312 | "opam": 313 | "opam-version: \"1.2\"\nmaintainer: \"opensource@janestreet.com\"\nauthors: \"Jane Street Group, LLC \"\nlicense: \"Apache-2.0\"\nhomepage: \"https://github.com/janestreet/ppx_sexp_conv\"\nbug-reports: \"https://github.com/janestreet/ppx_sexp_conv/issues\"\ndepends: [\n \"base\" {>= \"v0.11\" & < \"v0.12\"}\n \"jbuilder\" {build & >= \"1.0+beta18.1\"}\n \"ocaml-migrate-parsetree\" {>= \"1.0\"}\n \"ppxlib\" {>= \"0.3.0\"}\n]\nconflicts: [\n \"jbuilder\" {= \"1.0+beta19\"}\n]\navailable: ocaml-version >= \"4.04.1\"\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git+https://github.com/janestreet/ppx_sexp_conv.git\"", 314 | "override": null 315 | } 316 | }, 317 | "dependencies": [ 318 | "@esy-ocaml/substs@0.0.1", "@opam/base@opam:v0.11.1", 319 | "@opam/jbuilder@opam:transition", 320 | "@opam/ocaml-migrate-parsetree@opam:1.0.11", 321 | "@opam/ppxlib@opam:0.3.0" 322 | ] 323 | }, 324 | "@opam/ppx_let@opam:v0.11.0": { 325 | "record": { 326 | "name": "@opam/ppx_let", 327 | "version": "opam:v0.11.0", 328 | "source": [ 329 | "archive:https://opam.ocaml.org/archives/ppx_let.v0.11.0+opam.tar.gz#md5:2b3b58848f7eabe62ac48895f6868a89", 330 | "archive:https://ocaml.janestreet.com/ocaml-core/v0.11/files/ppx_let-v0.11.0.tar.gz#md5:40d1798d7724816c65eb5cdabd20f150" 331 | ], 332 | "files": [], 333 | "opam": { 334 | "name": "ppx_let", 335 | "version": "v0.11.0", 336 | "opam": 337 | "opam-version: \"1.2\"\nmaintainer: \"opensource@janestreet.com\"\nauthors: \"Jane Street Group, LLC \"\nlicense: \"Apache-2.0\"\nhomepage: \"https://github.com/janestreet/ppx_let\"\nbug-reports: \"https://github.com/janestreet/ppx_let/issues\"\ndepends: [\n \"base\" {>= \"v0.11\" & < \"v0.12\"}\n \"jbuilder\" {build & >= \"1.0+beta18.1\"}\n \"ocaml-migrate-parsetree\" {>= \"1.0\"}\n \"ppxlib\" {>= \"0.1.0\"}\n]\nconflicts: [\n \"jbuilder\" {= \"1.0+beta19\"}\n]\navailable: ocaml-version >= \"4.04.1\"\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git+https://github.com/janestreet/ppx_let.git\"", 338 | "override": null 339 | } 340 | }, 341 | "dependencies": [ 342 | "@esy-ocaml/substs@0.0.1", "@opam/base@opam:v0.11.1", 343 | "@opam/jbuilder@opam:transition", 344 | "@opam/ocaml-migrate-parsetree@opam:1.0.11", 345 | "@opam/ppxlib@opam:0.3.0" 346 | ] 347 | }, 348 | "@opam/ppx_derivers@opam:1.0": { 349 | "record": { 350 | "name": "@opam/ppx_derivers", 351 | "version": "opam:1.0", 352 | "source": [ 353 | "archive:https://opam.ocaml.org/archives/ppx_derivers.1.0+opam.tar.gz#md5:7b1cfb4260512d4b2e9d45213c3cba2a", 354 | "archive:https://github.com/ocaml-ppx/ppx_derivers/archive/1.0.tar.gz#md5:4ddce8f43fdb9b0ef0ab6a7cbfebc3e3" 355 | ], 356 | "files": [], 357 | "opam": { 358 | "name": "ppx_derivers", 359 | "version": "1.0", 360 | "opam": 361 | "opam-version: \"1.2\"\nmaintainer: \"jeremie@dimino.org\"\nauthors: \"Jérémie Dimino\"\nlicense: \"BSD3\"\nhomepage: \"https://github.com/ocaml-ppx/ppx_derivers\"\nbug-reports: \"https://github.com/ocaml-ppx/ppx_derivers/issues\"\ndepends: [\n \"jbuilder\" {build & >= \"1.0+beta7\"}\n]\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git://github.com/ocaml-ppx/ppx_derivers.git\"", 362 | "override": null 363 | } 364 | }, 365 | "dependencies": [ 366 | "@esy-ocaml/substs@0.0.1", "@opam/jbuilder@opam:transition" 367 | ] 368 | }, 369 | "@opam/ppx_compare@opam:v0.11.1": { 370 | "record": { 371 | "name": "@opam/ppx_compare", 372 | "version": "opam:v0.11.1", 373 | "source": [ 374 | "archive:https://opam.ocaml.org/archives/ppx_compare.v0.11.1+opam.tar.gz#md5:4c565efeb3ce0fd0c00de1baa28caaa0", 375 | "archive:https://github.com/janestreet/ppx_compare/archive/v0.11.1.tar.gz#md5:3df1a90fc90d180b1f96cdd30e64145d" 376 | ], 377 | "files": [], 378 | "opam": { 379 | "name": "ppx_compare", 380 | "version": "v0.11.1", 381 | "opam": 382 | "opam-version: \"1.2\"\nmaintainer: \"opensource@janestreet.com\"\nauthors: \"Jane Street Group, LLC \"\nlicense: \"Apache-2.0\"\nhomepage: \"https://github.com/janestreet/ppx_compare\"\nbug-reports: \"https://github.com/janestreet/ppx_compare/issues\"\ndepends: [\n \"base\" {>= \"v0.11\" & < \"v0.12\"}\n \"jbuilder\" {build & >= \"1.0+beta18.1\"}\n \"ocaml-migrate-parsetree\" {>= \"1.0\"}\n \"ppxlib\" {>= \"0.3.0\"}\n]\nconflicts: [\n \"jbuilder\" {= \"1.0+beta19\"}\n]\navailable: ocaml-version >= \"4.04.1\"\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git+https://github.com/janestreet/ppx_compare.git\"", 383 | "override": null 384 | } 385 | }, 386 | "dependencies": [ 387 | "@esy-ocaml/substs@0.0.1", "@opam/base@opam:v0.11.1", 388 | "@opam/jbuilder@opam:transition", 389 | "@opam/ocaml-migrate-parsetree@opam:1.0.11", 390 | "@opam/ppxlib@opam:0.3.0" 391 | ] 392 | }, 393 | "@opam/parsexp@opam:v0.11.0": { 394 | "record": { 395 | "name": "@opam/parsexp", 396 | "version": "opam:v0.11.0", 397 | "source": [ 398 | "archive:https://opam.ocaml.org/archives/parsexp.v0.11.0+opam.tar.gz#md5:33f3288c68f18df2dadb471763ff8792", 399 | "archive:https://ocaml.janestreet.com/ocaml-core/v0.11/files/parsexp-v0.11.0.tar.gz#md5:816fce8d14b71a379296577c803bdbca" 400 | ], 401 | "files": [], 402 | "opam": { 403 | "name": "parsexp", 404 | "version": "v0.11.0", 405 | "opam": 406 | "opam-version: \"1.2\"\nmaintainer: \"opensource@janestreet.com\"\nauthors: \"Jane Street Group, LLC \"\nlicense: \"Apache-2.0\"\nhomepage: \"https://github.com/janestreet/parsexp\"\nbug-reports: \"https://github.com/janestreet/parsexp/issues\"\ndepends: [\n \"sexplib0\" {>= \"v0.11\" & < \"v0.12\"}\n \"jbuilder\" {build & >= \"1.0+beta18.1\"}\n]\navailable: ocaml-version >= \"4.04.1\"\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git+https://github.com/janestreet/parsexp.git\"", 407 | "override": null 408 | } 409 | }, 410 | "dependencies": [ 411 | "@esy-ocaml/substs@0.0.1", "@opam/jbuilder@opam:transition", 412 | "@opam/sexplib0@opam:v0.11.0" 413 | ] 414 | }, 415 | "@opam/ocamlformat_support@opam:0.4": { 416 | "record": { 417 | "name": "@opam/ocamlformat_support", 418 | "version": "opam:0.4", 419 | "source": [ 420 | "archive:https://opam.ocaml.org/archives/ocamlformat_support.0.4+opam.tar.gz#md5:e94ef10cde6ec4313413ff190fe6a8ab", 421 | "archive:https://github.com/ocaml-ppx/ocamlformat/archive/support.0.4.tar.gz#md5:ec5f96a2727821f55ac50e305095208a" 422 | ], 423 | "files": [], 424 | "opam": { 425 | "name": "ocamlformat_support", 426 | "version": "0.4", 427 | "opam": 428 | "opam-version: \"1.2\"\nmaintainer: \"OCamlFormat Team \"\nauthors: \"Pierre Weis\"\nlicense: \"LGPL-2 with OCaml linking exception\"\nhomepage: \"https://github.com/ocaml-ppx/ocamlformat/tree/support\"\nbug-reports: \"https://github.com/ocaml-ppx/ocamlformat/issues\"\ndepends: [\n \"jbuilder\" {build & >= \"1.0+beta7\"}\n]\navailable: ocaml-version >= \"4.04.0\"\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git+https://github.com/ocaml-ppx/ocamlformat.git#support\"", 429 | "override": null 430 | } 431 | }, 432 | "dependencies": [ 433 | "@esy-ocaml/substs@0.0.1", "@opam/jbuilder@opam:transition" 434 | ] 435 | }, 436 | "@opam/ocamlformat@opam:0.6": { 437 | "record": { 438 | "name": "@opam/ocamlformat", 439 | "version": "opam:0.6", 440 | "source": [ 441 | "archive:https://opam.ocaml.org/archives/ocamlformat.0.6+opam.tar.gz#md5:3628ff1cabf632bf93b326dc4d6e3c53", 442 | "archive:https://github.com/ocaml-ppx/ocamlformat/archive/0.6.tar.gz#md5:73b1dea352fa121f5656d1fd651ad10d" 443 | ], 444 | "files": [], 445 | "opam": { 446 | "name": "ocamlformat", 447 | "version": "0.6", 448 | "opam": 449 | "opam-version: \"1.2\"\nmaintainer: \"OCamlFormat Team \"\nauthors: \"Josh Berdine \"\nlicense: \"MIT\"\nhomepage: \"https://github.com/ocaml-ppx/ocamlformat\"\nbug-reports: \"https://github.com/ocaml-ppx/ocamlformat/issues\"\ndepends: [\n \"base\" {>= \"v0.11.0\"}\n \"base-unix\"\n \"cmdliner\"\n \"jbuilder\" {build & >= \"1.0+beta20\"}\n \"ocaml-migrate-parsetree\" {>= \"1.0.6\"}\n \"ocamlformat_support\" {>= \"0.4\" & < \"0.5\"}\n \"stdio\"\n]\navailable: ocaml-version >= \"4.04.1\"\nbuild: [\n [\"tools/gen_version.sh\" \"src/Version.ml\" version] {pinned}\n [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\n]\ndev-repo: \"git+https://github.com/ocaml-ppx/ocamlformat.git\"", 450 | "override": null 451 | } 452 | }, 453 | "dependencies": [ 454 | "@esy-ocaml/substs@0.0.1", "@opam/base@opam:v0.11.1", 455 | "@opam/base-unix@opam:base", "@opam/cmdliner@opam:1.0.2", 456 | "@opam/jbuilder@opam:transition", 457 | "@opam/ocaml-migrate-parsetree@opam:1.0.11", 458 | "@opam/ocamlformat_support@opam:0.4", "@opam/stdio@opam:v0.11.0" 459 | ] 460 | }, 461 | "@opam/ocamlfind@opam:1.8.0": { 462 | "record": { 463 | "name": "@opam/ocamlfind", 464 | "version": "opam:1.8.0", 465 | "source": [ 466 | "archive:https://opam.ocaml.org/archives/ocamlfind.1.8.0+opam.tar.gz#md5:4d70eaf49e0f5f4d84257391088da0a2", 467 | "archive:http://download.camlcity.org/download/findlib-1.8.0.tar.gz#md5:a710c559667672077a93d34eb6a42e5b", 468 | "archive:http://download2.camlcity.org/download/findlib-1.8.0.tar.gz#md5:a710c559667672077a93d34eb6a42e5b" 469 | ], 470 | "files": [ 471 | { 472 | "name": "ocaml-stub", 473 | "content": 474 | "#!/bin/sh\n\nBINDIR=$(dirname \"$(command -v ocamlc)\")\n\"$BINDIR/ocaml\" -I \"$OCAML_TOPLEVEL_PATH\" \"$@\"\n" 475 | }, 476 | { 477 | "name": "ocamlfind.install", 478 | "content": 479 | "bin: [\n \"src/findlib/ocamlfind\" {\"ocamlfind\"}\n \"?src/findlib/ocamlfind_opt\" {\"ocamlfind\"}\n \"?tools/safe_camlp4\"\n]\ntoplevel: [\"src/findlib/topfind\"]\n" 480 | }, 481 | { 482 | "name": "_esy/build", 483 | "content": 484 | "#!/bin/bash\n\nset -euo pipefail\nset -x\n\n#\n# Shim OCAMLLIB so that we can write topfind there\n#\n\nREAL_OCAMLLIB=\"$1\"\n\nmkdir -p $cur__install/lib/ocaml\ncd $cur__install/lib/ocaml\n\nfor filename in `ls -1 $REAL_OCAMLLIB`; do\n ln -s $REAL_OCAMLLIB/$filename $filename;\ndone\n\n#\n# Build\n#\n\ncd $cur__root\n\nexport OCAMLLIB=\"$cur__install/lib/ocaml\"\n\n./configure \\\n -bindir $cur__install/bin \\\n -sitelib $cur__install/lib \\\n -mandir $cur__install/man \\\n -config $cur__install/lib/findlib.conf \\\n -no-custom \\\n -no-camlp4\n\nmake all\nmake opt\nmake install\n\n(opam-installer --prefix=$cur__install || true)\n" 485 | } 486 | ], 487 | "opam": { 488 | "name": "ocamlfind", 489 | "version": "1.8.0", 490 | "opam": 491 | "opam-version: \"1.2\"\nmaintainer: \"Thomas Gazagnaire \"\nauthors: \"Gerd Stolpmann \"\nhomepage: \"http://projects.camlcity.org/projects/findlib.html\"\nbug-reports: \"https://gitlab.camlcity.org/gerd/lib-findlib/issues\"\ndepends: [\n \"conf-m4\" {build}\n]\navailable: ocaml-version >= \"4.00.0\"\nbuild: [\n [\n \"./configure\"\n \"-bindir\"\n bin\n \"-sitelib\"\n lib\n \"-mandir\"\n man\n \"-config\"\n \"%{lib}%/findlib.conf\"\n \"-no-custom\"\n \"-no-topfind\" {preinstalled}\n ]\n [make \"all\"]\n [make \"opt\"] {ocaml-native}\n]\ninstall: [\n [make \"install\"]\n [\"install\" \"-m\" \"0755\" \"ocaml-stub\" \"%{bin}%/ocaml\"] {preinstalled}\n]\nremove: [\n [\"ocamlfind\" \"remove\" \"bytes\"]\n [\n \"./configure\"\n \"-bindir\"\n bin\n \"-sitelib\"\n lib\n \"-mandir\"\n man\n \"-config\"\n \"%{lib}%/findlib.conf\"\n \"-no-topfind\" {preinstalled}\n ]\n [make \"uninstall\"]\n [\"rm\" \"-f\" \"%{bin}%/ocaml\"] {preinstalled}\n]\ndev-repo: \"git+https://gitlab.camlcity.org/gerd/lib-findlib.git\"", 492 | "override": { 493 | "build": [ [ "bash", "./_esy/build", "#{ocaml.lib / 'ocaml'}" ] ], 494 | "exportedEnv": { 495 | "OCAMLLIB": { 496 | "val": "#{@opam/ocamlfind.install / 'lib' / 'ocaml'}", 497 | "scope": "global" 498 | }, 499 | "CAML_LD_LIBRARY_PATH": { 500 | "val": 501 | "#{@opam/ocamlfind.install / 'lib' / 'ocaml' / 'stublibs' : @opam/ocamlfind.install / 'lib' / 'ocaml' : $CAML_LD_LIBRARY_PATH}", 502 | "scope": "global" 503 | }, 504 | "OCAML_TOPLEVEL_PATH": { 505 | "val": "#{@opam/ocamlfind.install / 'lib' / 'ocaml'}", 506 | "scope": "global" 507 | } 508 | } 509 | } 510 | } 511 | }, 512 | "dependencies": [ "@esy-ocaml/substs@0.0.1", "@opam/conf-m4@opam:1" ] 513 | }, 514 | "@opam/ocamlbuild@opam:0.12.0": { 515 | "record": { 516 | "name": "@opam/ocamlbuild", 517 | "version": "opam:0.12.0", 518 | "source": [ 519 | "archive:https://opam.ocaml.org/archives/ocamlbuild.0.12.0+opam.tar.gz#md5:6e877d7f40c119c0c6c03f04342f2264", 520 | "archive:https://github.com/ocaml/ocamlbuild/archive/0.12.0.tar.gz#md5:442baa19470bd49150f153122e22907b" 521 | ], 522 | "files": [], 523 | "opam": { 524 | "name": "ocamlbuild", 525 | "version": "0.12.0", 526 | "opam": 527 | "opam-version: \"1.2\"\nmaintainer: \"Gabriel Scherer \"\nauthors: [\"Nicolas Pouillard\" \"Berke Durak\"]\nlicense: \"LGPL-2 with OCaml linking exception\"\nhomepage: \"https://github.com/ocaml/ocamlbuild/\"\ndoc: \"https://github.com/ocaml/ocamlbuild/blob/master/manual/manual.adoc\"\nbug-reports: \"https://github.com/ocaml/ocamlbuild/issues\"\nconflicts: [\n \"base-ocamlbuild\"\n \"ocamlfind\" {< \"1.6.2\"}\n]\navailable: ocaml-version >= \"4.03\"\nbuild: [\n [\n make\n \"-f\"\n \"configure.make\"\n \"all\"\n \"OCAMLBUILD_PREFIX=%{prefix}%\"\n \"OCAMLBUILD_BINDIR=%{bin}%\"\n \"OCAMLBUILD_LIBDIR=%{lib}%\"\n \"OCAMLBUILD_MANDIR=%{man}%\"\n \"OCAML_NATIVE=%{ocaml-native}%\"\n \"OCAML_NATIVE_TOOLS=%{ocaml-native}%\"\n ]\n [make \"check-if-preinstalled\" \"all\" \"opam-install\"]\n]\ndev-repo: \"git+https://github.com/ocaml/ocamlbuild.git\"", 528 | "override": null 529 | } 530 | }, 531 | "dependencies": [ "@esy-ocaml/substs@0.0.1" ] 532 | }, 533 | "@opam/ocaml-migrate-parsetree@opam:1.0.11": { 534 | "record": { 535 | "name": "@opam/ocaml-migrate-parsetree", 536 | "version": "opam:1.0.11", 537 | "source": [ 538 | "archive:https://opam.ocaml.org/archives/ocaml-migrate-parsetree.1.0.11+opam.tar.gz#md5:d3ac8978ae2f0554ac77912e94abed3b", 539 | "archive:https://github.com/ocaml-ppx/ocaml-migrate-parsetree/releases/download/v1.0.11/ocaml-migrate-parsetree-1.0.11.tbz#md5:26bb1b038de81a79d43ed95c282b2b71" 540 | ], 541 | "files": [], 542 | "opam": { 543 | "name": "ocaml-migrate-parsetree", 544 | "version": "1.0.11", 545 | "opam": 546 | "opam-version: \"1.2\"\nmaintainer: \"frederic.bour@lakaban.net\"\nauthors: [\n \"Frédéric Bour \"\n \"Jérémie Dimino \"\n]\nlicense: \"LGPL-2.1\"\ntags: [\"syntax\" \"org:ocamllabs\"]\nhomepage: \"https://github.com/ocaml-ppx/ocaml-migrate-parsetree\"\nbug-reports: \"https://github.com/ocaml-ppx/ocaml-migrate-parsetree/issues\"\ndepends: [\n \"result\"\n \"ocamlfind\" {build}\n \"dune\" {build}\n]\navailable: ocaml-version >= \"4.02.0\"\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git://github.com/ocaml-ppx/ocaml-migrate-parsetree.git\"", 547 | "override": null 548 | } 549 | }, 550 | "dependencies": [ 551 | "@esy-ocaml/substs@0.0.1", "@opam/dune@opam:1.0.1", 552 | "@opam/ocamlfind@opam:1.8.0", "@opam/result@opam:1.3" 553 | ] 554 | }, 555 | "@opam/ocaml-compiler-libs@opam:v0.11.0": { 556 | "record": { 557 | "name": "@opam/ocaml-compiler-libs", 558 | "version": "opam:v0.11.0", 559 | "source": [ 560 | "archive:https://opam.ocaml.org/archives/ocaml-compiler-libs.v0.11.0+opam.tar.gz#md5:bbf105e8837058bcc2c42b9b7409e1f6", 561 | "archive:https://ocaml.janestreet.com/ocaml-core/v0.11/files/ocaml-compiler-libs-v0.11.0.tar.gz#md5:e170c16186aa55b7e8b11e461418a10a" 562 | ], 563 | "files": [], 564 | "opam": { 565 | "name": "ocaml-compiler-libs", 566 | "version": "v0.11.0", 567 | "opam": 568 | "opam-version: \"1.2\"\nmaintainer: \"opensource@janestreet.com\"\nauthors: \"Jane Street Group, LLC \"\nlicense: \"Apache-2.0\"\nhomepage: \"https://github.com/janestreet/ocaml-compiler-libs\"\nbug-reports: \"https://github.com/janestreet/ocaml-compiler-libs/issues\"\ndepends: [\n \"jbuilder\" {build & >= \"1.0+beta12\"}\n]\navailable: ocaml-version >= \"4.04.1\"\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git+https://github.com/janestreet/ocaml-compiler-libs.git\"", 569 | "override": null 570 | } 571 | }, 572 | "dependencies": [ 573 | "@esy-ocaml/substs@0.0.1", "@opam/jbuilder@opam:transition" 574 | ] 575 | }, 576 | "@opam/num@opam:1.1": { 577 | "record": { 578 | "name": "@opam/num", 579 | "version": "opam:1.1", 580 | "source": [ 581 | "archive:https://opam.ocaml.org/archives/num.1.1+opam.tar.gz#md5:1567cb86d261a416147807d830c22520", 582 | "archive:https://github.com/ocaml/num/archive/v1.1.tar.gz#md5:710cbe18b144955687a03ebab439ff2b" 583 | ], 584 | "files": [ 585 | { 586 | "name": "findlib-install.patch", 587 | "content": 588 | "From 7688bb4fea24463c92e9c4870acc08495a4c77cb Mon Sep 17 00:00:00 2001\nFrom: David Allsopp \nDate: Wed, 10 Jan 2018 15:20:46 +0000\nSubject: [PATCH] Provide findlib-install target\n\nAllows installing the entire library using ocamlfind.\n---\n Makefile | 10 +++++++++-\n src/META | 17 -----------------\n src/META.in | 19 +++++++++++++++++++\n src/Makefile | 17 +++++++++++++++--\n 4 files changed, 43 insertions(+), 20 deletions(-)\n delete mode 100644 src/META\n create mode 100644 src/META.in\n\ndiff --git a/Makefile b/Makefile\nindex 6a5d08f..b40e588 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -14,8 +14,16 @@ install:\n \t$(MAKE) -C src install\n \t$(MAKE) -C toplevel install\n \n+findlib-install:\n+\t$(MAKE) -C src findlib-install\n+\t$(MAKE) -C toplevel install\n+\n uninstall:\n \t$(MAKE) -C src uninstall\n \t$(MAKE) -C toplevel uninstall\n \n-.PHONY: all test clean install uninstall\n+findlib-uninstall:\n+\t$(MAKE) -C src findlib-uninstall\n+\t$(MAKE) -C toplevel uninstall\n+\n+.PHONY: all test clean install uninstall findlib-install findlib-uninstall\ndiff --git a/src/META b/src/META\ndeleted file mode 100644\nindex 66ac170..0000000\n--- a/src/META\n+++ /dev/null\n@@ -1,17 +0,0 @@\n-# This META is the one provided by findlib when the \"num\" library was\n-# part of the core OCaml distribution. For backward compatibility,\n-# it installs into OCaml's standard library directory, not in a subdirectory\n-\n-requires = \"num.core\"\n-requires(toploop) = \"num.core,num-top\"\n-version = \"1.0\"\n-description = \"Arbitrary-precision rational arithmetic\"\n-package \"core\" (\n- directory = \"^\"\n- version = \"1.0\"\n- browse_interfaces = \"\"\n- archive(byte) = \"nums.cma\"\n- archive(native) = \"nums.cmxa\"\n- plugin(byte) = \"nums.cma\"\n- plugin(native) = \"nums.cmxs\"\n-)\ndiff --git a/src/META.in b/src/META.in\nnew file mode 100644\nindex 0000000..b5678b7\n--- /dev/null\n+++ b/src/META.in\n@@ -0,0 +1,19 @@\n+# This META is the one provided by findlib when the \"num\" library was\n+# part of the core OCaml distribution. For backward compatibility,\n+# it is installed into OCaml's standard library directory. If the\n+# directory line below is removed, then it's installed in a\n+# subdirectory, as normal for a findlib package.\n+\n+requires = \"num.core\"\n+requires(toploop) = \"num.core,num-top\"\n+version = \"1.0\"\n+description = \"Arbitrary-precision rational arithmetic\"\n+package \"core\" (\n+ directory = \"^\"\n+ version = \"1.0\"\n+ browse_interfaces = \"\"\n+ archive(byte) = \"nums.cma\"\n+ archive(native) = \"nums.cmxa\"\n+ plugin(byte) = \"nums.cma\"\n+ plugin(native) = \"nums.cmxs\"\n+)\ndiff --git a/src/Makefile b/src/Makefile\nindex 97dc074..ff271fe 100644\n--- a/src/Makefile\n+++ b/src/Makefile\n@@ -80,21 +80,34 @@ endif\n ifeq \"$(NATDYNLINK)\" \"true\"\n TOINSTALL+=nums.cmxs\n endif\n+ifeq \"$(SUPPORTS_SHARED_LIBRARIES)\" \"true\"\n TOINSTALL_STUBS=dllnums.$(SO)\n+else\n+TOINSTALL_STUBS=\n+endif\n \n install:\n+\tcp META.in META\n \t$(OCAMLFIND) install num META\n+\trm -f META\n \t$(INSTALL_DATA) $(TOINSTALL) $(STDLIBDIR)\n ifeq \"$(SUPPORTS_SHARED_LIBRARIES)\" \"true\"\n \t$(INSTALL_DLL) $(TOINSTALL_STUBS) $(STDLIBDIR)/stublibs\n endif\n \n-uninstall:\n+findlib-install:\n+\tgrep -Fv '^' META.in > META\n+\t$(OCAMLFIND) install num META $(TOINSTALL) $(TOINSTALL_STUBS)\n+\trm -f META\n+\n+findlib-uninstall:\n+\t$(OCAMLFIND) remove num\n+\n+uninstall: findlib-uninstall\n \tcd $(STDLIBDIR) && rm -f $(TOINSTALL)\n ifeq \"$(SUPPORTS_SHARED_LIBRARIES)\" \"true\"\n \tcd $(STDLIBDIR)/stublibs && rm -f $(TOINSTALL_STUBS) \n endif\n-\t$(OCAMLFIND) remove num\n \n clean:\n \trm -f *.cm[ioxta] *.cmx[as] *.cmti *.$(O) *.$(A) *.$(SO)\n-- \n2.14.1\n\n" 589 | }, 590 | { 591 | "name": "installation-warning.patch", 592 | "content": 593 | "From db8d748b2cad0adc2698e9fcf28727083a711bae Mon Sep 17 00:00:00 2001\nFrom: David Allsopp \nDate: Wed, 24 Jan 2018 16:01:56 +0000\nSubject: [PATCH] Warn about installations broken by previous faulty package\n\n---\n Makefile | 33 +++++++++++++++++++++++++++++++++\n 1 file changed, 33 insertions(+)\n\ndiff --git a/Makefile b/Makefile\nindex b40e588..d4dcd70 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -14,9 +14,42 @@ install:\n \t$(MAKE) -C src install\n \t$(MAKE) -C toplevel install\n \n+OCAMLFIND_DIR:=$(dir $(shell command -v ocamlfind 2>/dev/null))\n+OCAMLC_DIR:=$(dir $(shell command -v ocamlc 2>/dev/null))\n+NUM_INSTALLED:=$(shell ocamlfind query num 2>/dev/null)\n+\n+ifeq ($(NUM_INSTALLED),)\n+# The num findlib package is not already present - wohoo!\n+OUR_FAULT=no\n+else\n+ifeq ($(OCAMLFIND_DIR),$(OCAMLC_DIR))\n+# The num findlib package is present, but ocamlc and ocamlfind are in the\n+# same place, which means that either we're looking at a system-installed\n+# ocamlfind (which isn't supported), or the user has done something else\n+# nefarious and doesn't deserve our sympathy (or, at least, our potentially\n+# unhelpful advice)\n+OUR_FAULT=no\n+else\n+# The num findlib package package is present, and ocamlc and ocamlfind reside\n+# in different directories, which means that we're almost certainly looking at\n+# a system switch which has been damaged by a previous num package installation\n+# on an OS which didn't protect the system lib directory.\n+OUR_FAULT=probably\n+endif\n+endif\n+\n findlib-install:\n+ifeq ($(OUR_FAULT),no)\n \t$(MAKE) -C src findlib-install\n \t$(MAKE) -C toplevel install\n+else\n+\t@echo \"\\033[0;31m[ERROR]\\033[m It appears that the num library was previously installed to your system\"\n+\t@echo \" compiler's lib directory, probably by a faulty opam package.\"\n+\t@echo \" You will need to remove arith_flags.*, arith_status.*, big_int.*,\"\n+\t@echo \" int_misc.*, nat.*, num.*, ratio.*, nums.*, libnums.* and\"\n+\t@echo \" stublibs/dllnums.* from $(shell ocamlc -where).\"\n+\t@false\n+endif\n \n uninstall:\n \t$(MAKE) -C src uninstall\n-- \n2.14.1\n\n" 594 | } 595 | ], 596 | "opam": { 597 | "name": "num", 598 | "version": "1.1", 599 | "opam": 600 | "opam-version: \"1.2\"\nname: \"num\"\nversion: \"1.1\"\nmaintainer: \"Xavier Leroy \"\nauthors: [\"Valérie Ménissier-Morain\" \"Pierre Weis\" \"Xavier Leroy\"]\nlicense: \"LGPL 2.1 with OCaml linking exception\"\nhomepage: \"https://github.com/ocaml/num/\"\nbug-reports: \"https://github.com/ocaml/num/issues\"\ndepends: [\n \"ocamlfind\" {build & >= \"1.7.3\"}\n]\nconflicts: [\"base-num\"]\navailable: ocaml-version >= \"4.06.0\"\nbuild: make\ninstall: [\n make\n \"install\" {!preinstalled}\n \"findlib-install\" {preinstalled}\n]\nremove: [\n make\n \"uninstall\" {!preinstalled}\n \"findlib-uninstall\" {preinstalled}\n]\npatches: [\"findlib-install.patch\" \"installation-warning.patch\"]\ndev-repo: \"git+https://github.com/ocaml/num.git\"", 601 | "override": { 602 | "build": [ [ "make" ] ], 603 | "install": [ [ "make", "findlib-install" ] ], 604 | "exportedEnv": { 605 | "CAML_LD_LIBRARY_PATH": { 606 | "val": 607 | "#{self.install / 'lib' / 'num' : $CAML_LD_LIBRARY_PATH}", 608 | "scope": "global" 609 | } 610 | } 611 | } 612 | } 613 | }, 614 | "dependencies": [ 615 | "@esy-ocaml/substs@0.0.1", "@opam/ocamlfind@opam:1.8.0" 616 | ] 617 | }, 618 | "@opam/merlin-extend@opam:0.3": { 619 | "record": { 620 | "name": "@opam/merlin-extend", 621 | "version": "opam:0.3", 622 | "source": [ 623 | "archive:https://opam.ocaml.org/archives/merlin-extend.0.3+opam.tar.gz#md5:5bc02f7e256c5a2e99e8dc01b26b81c2", 624 | "archive:https://github.com/let-def/merlin-extend/archive/v0.3.tar.gz#md5:9c6dfd4f53328f02f12fcc265f4e2dda" 625 | ], 626 | "files": [], 627 | "opam": { 628 | "name": "merlin-extend", 629 | "version": "0.3", 630 | "opam": 631 | "opam-version: \"1.2\"\nmaintainer: \"Frederic Bour \"\nauthors: \"Frederic Bour \"\nlicense: \"MIT\"\nhomepage: \"https://github.com/let-def/merlin-extend\"\nbug-reports: \"https://github.com/let-def/merlin-extend\"\ndepends: [\n \"ocamlfind\" {build}\n \"cppo\" {build}\n]\navailable: ocaml-version >= \"4.02.3\"\nbuild: make\ninstall: [make \"install\"]\nremove: [\"ocamlfind\" \"remove\" \"merlin_extend\"]\ndev-repo: \"git+https://github.com/let-def/merlin-extend.git\"", 632 | "override": null 633 | } 634 | }, 635 | "dependencies": [ 636 | "@esy-ocaml/substs@0.0.1", "@opam/cppo@opam:1.6.4", 637 | "@opam/ocamlfind@opam:1.8.0" 638 | ] 639 | }, 640 | "@opam/merlin@opam:3.1.0": { 641 | "record": { 642 | "name": "@opam/merlin", 643 | "version": "opam:3.1.0", 644 | "source": [ 645 | "archive:https://opam.ocaml.org/archives/merlin.3.1.0+opam.tar.gz#md5:628c8602e554657054dd097314bae9dc", 646 | "archive:https://github.com/ocaml/merlin/archive/v3.1.0.tar.gz#md5:6e066ed35b59d286d8e053c2f25cbc0d" 647 | ], 648 | "files": [], 649 | "opam": { 650 | "name": "merlin", 651 | "version": "3.1.0", 652 | "opam": 653 | "opam-version: \"1.2\"\nmaintainer: \"defree@gmail.com\"\nauthors: \"The Merlin team\"\nhomepage: \"https://github.com/ocaml/merlin\"\nbug-reports: \"https://github.com/ocaml/merlin/issues\"\ndepends: [\n \"ocamlfind\" {>= \"1.5.2\"}\n \"yojson\"\n]\navailable: ocaml-version >= \"4.02.1\" & ocaml-version < \"4.08\"\nbuild: [\n [\"./configure\" \"--prefix\" prefix]\n [\"rm\" \"-rf\" \"%{prefix}%/share/ocamlmerlin\"]\n [make \"-j\" jobs]\n]\npost-messages:\n \"\"\"\nmerlin installed.\n\nQuick setup for VIM\n-------------------\nAppend this to your .vimrc to add merlin to vim's runtime-path:\n let g:opamshare = substitute(system('opam config var share'),'\\\\n$','','''')\n execute \"set rtp+=\" . g:opamshare . \"/merlin/vim\"\n\nAlso run the following line in vim to index the documentation:\n :execute \"helptags \" . g:opamshare . \"/merlin/vim/doc\"\n\nQuick setup for EMACS\n-------------------\nAdd opam emacs directory to your load-path by appending this to your .emacs:\n (let ((opam-share (ignore-errors (car (process-lines \"opam\" \"config\" \"var\" \"share\")))))\n (when (and opam-share (file-directory-p opam-share))\n ;; Register Merlin\n (add-to-list 'load-path (expand-file-name \"emacs/site-lisp\" opam-share))\n (autoload 'merlin-mode \"merlin\" nil t nil)\n ;; Automatically start it in OCaml buffers\n (add-hook 'tuareg-mode-hook 'merlin-mode t)\n (add-hook 'caml-mode-hook 'merlin-mode t)\n ;; Use opam switch to lookup ocamlmerlin binary\n (setq merlin-command 'opam)))\n\nTake a look at https://github.com/ocaml/merlin for more information\n\nQuick setup with opam-user-setup\n--------------------------------\n\nOpam-user-setup support Merlin.\n\n $ opam user-setup install\n\nshould take care of basic setup.\nSee https://github.com/OCamlPro/opam-user-setup\"\"\"\n {success & !user-setup:installed}\ndev-repo: \"git+https://github.com/ocaml/merlin.git\"", 654 | "override": null 655 | } 656 | }, 657 | "dependencies": [ 658 | "@esy-ocaml/substs@0.0.1", "@opam/ocamlfind@opam:1.8.0", 659 | "@opam/yojson@opam:1.4.1" 660 | ] 661 | }, 662 | "@opam/menhir@opam:20171013": { 663 | "record": { 664 | "name": "@opam/menhir", 665 | "version": "opam:20171013", 666 | "source": [ 667 | "archive:https://opam.ocaml.org/archives/menhir.20171013+opam.tar.gz#md5:b361a87378407e26b9ea2dde7ddf41a0", 668 | "archive:http://gallium.inria.fr/~fpottier/menhir/menhir-20171013.tar.gz#md5:620863edea40437390ee5e5bd82fba11" 669 | ], 670 | "files": [], 671 | "opam": { 672 | "name": "menhir", 673 | "version": "20171013", 674 | "opam": 675 | "opam-version: \"1.2\"\nmaintainer: \"francois.pottier@inria.fr\"\nauthors: [\n \"François Pottier \"\n \"Yann Régis-Gianas \"\n]\nhomepage: \"http://gallium.inria.fr/~fpottier/menhir/\"\nbug-reports: \"menhir@inria.fr\"\ndepends: [\n \"ocamlfind\"\n \"ocamlbuild\" {build}\n]\navailable: ocaml-version >= \"4.02\"\nbuild: [\n make\n \"-f\"\n \"Makefile\"\n \"PREFIX=%{prefix}%\"\n \"USE_OCAMLFIND=true\"\n \"docdir=%{doc}%/menhir\"\n \"libdir=%{lib}%/menhir\"\n \"mandir=%{man}%/man1\"\n]\ninstall: [\n make\n \"-f\"\n \"Makefile\"\n \"install\"\n \"PREFIX=%{prefix}%\"\n \"docdir=%{doc}%/menhir\"\n \"libdir=%{lib}%/menhir\"\n \"mandir=%{man}%/man1\"\n]\nremove: [\n make\n \"-f\"\n \"Makefile\"\n \"uninstall\"\n \"PREFIX=%{prefix}%\"\n \"docdir=%{doc}%/menhir\"\n \"libdir=%{lib}%/menhir\"\n \"mandir=%{man}%/man1\"\n]\ndev-repo: \"git+https://gitlab.inria.fr/fpottier/menhir.git\"", 676 | "override": null 677 | } 678 | }, 679 | "dependencies": [ 680 | "@esy-ocaml/substs@0.0.1", "@opam/ocamlbuild@opam:0.12.0", 681 | "@opam/ocamlfind@opam:1.8.0" 682 | ] 683 | }, 684 | "@opam/lwt_ppx@opam:1.2.1": { 685 | "record": { 686 | "name": "@opam/lwt_ppx", 687 | "version": "opam:1.2.1", 688 | "source": [ 689 | "archive:https://opam.ocaml.org/archives/lwt_ppx.1.2.1+opam.tar.gz#md5:e69b382de412410fd89dacf7dc6e8d3e", 690 | "archive:https://github.com/ocsigen/lwt/archive/4.1.0.tar.gz#md5:e919bee206f18b3d49250ecf9584fde7" 691 | ], 692 | "files": [], 693 | "opam": { 694 | "name": "lwt_ppx", 695 | "version": "1.2.1", 696 | "opam": 697 | "opam-version: \"1.2\"\nversion: \"1.2.1\"\nmaintainer: \"Anton Bachin \"\nauthors: \"Gabriel Radanne\"\nlicense: \"LGPL with OpenSSL linking exception\"\nhomepage: \"https://github.com/ocsigen/lwt\"\ndoc: \"https://ocsigen.org/lwt/api/Ppx_lwt\"\nbug-reports: \"https://github.com/ocsigen/lwt/issues\"\ndepends: [\n \"jbuilder\" {build & >= \"1.0+beta14\"}\n \"lwt\"\n \"ocaml-migrate-parsetree\"\n \"ppx_tools_versioned\" {>= \"5.0.1\"}\n]\navailable: ocaml-version >= \"4.02.0\"\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git+https://github.com/ocsigen/lwt.git\"", 698 | "override": null 699 | } 700 | }, 701 | "dependencies": [ 702 | "@esy-ocaml/substs@0.0.1", "@opam/jbuilder@opam:transition", 703 | "@opam/lwt@opam:4.1.0", "@opam/ocaml-migrate-parsetree@opam:1.0.11", 704 | "@opam/ppx_tools_versioned@opam:5.2" 705 | ] 706 | }, 707 | "@opam/lwt@opam:4.1.0": { 708 | "record": { 709 | "name": "@opam/lwt", 710 | "version": "opam:4.1.0", 711 | "source": [ 712 | "archive:https://opam.ocaml.org/archives/lwt.4.1.0+opam.tar.gz#md5:5c73061ac341ca56c2f1bd62728a0ad9", 713 | "archive:https://github.com/ocsigen/lwt/archive/4.1.0.tar.gz#md5:e919bee206f18b3d49250ecf9584fde7" 714 | ], 715 | "files": [], 716 | "opam": { 717 | "name": "lwt", 718 | "version": "4.1.0", 719 | "opam": 720 | "opam-version: \"1.2\"\nversion: \"4.1.0\"\nmaintainer: [\n \"Anton Bachin \"\n \"Mauricio Fernandez \"\n \"Simon Cruanes \"\n]\nauthors: [\"Jérôme Vouillon\" \"Jérémie Dimino\"]\nlicense: \"LGPL with OpenSSL linking exception\"\nhomepage: \"https://github.com/ocsigen/lwt\"\ndoc: \"https://ocsigen.org/lwt/manual/\"\nbug-reports: \"https://github.com/ocsigen/lwt/issues\"\ndepends: [\n \"cppo\" {build & >= \"1.1.0\"}\n \"jbuilder\" {build & >= \"1.0+beta14\"}\n \"ocamlfind\" {build & >= \"1.7.3-1\"}\n \"result\"\n]\ndepopts: [\"base-threads\" \"base-unix\" \"conf-libev\"]\navailable: ocaml-version >= \"4.02.0\" & compiler != \"4.02.1+BER\"\nbuild: [\n [\"ocaml\" \"src/util/configure.ml\" \"-use-libev\" \"%{conf-libev:installed}%\"]\n [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\n]\nmessages: [\n \"For the PPX, please install package lwt_ppx\" {!lwt_ppx:installed}\n \"For the Camlp4 syntax, please install package lwt_camlp4\"\n {camlp4:installed & !lwt_camlp4:installed}\n \"For Lwt_log and Lwt_daemon, please install package lwt_log\"\n {!lwt_log:installed}\n]\ndev-repo: \"git+https://github.com/ocsigen/lwt.git\"", 721 | "override": null 722 | } 723 | }, 724 | "dependencies": [ 725 | "@esy-ocaml/substs@0.0.1", "@opam/cppo@opam:1.6.4", 726 | "@opam/jbuilder@opam:transition", "@opam/ocamlfind@opam:1.8.0", 727 | "@opam/result@opam:1.3" 728 | ] 729 | }, 730 | "@opam/jbuilder@opam:transition": { 731 | "record": { 732 | "name": "@opam/jbuilder", 733 | "version": "opam:transition", 734 | "source": "no-source:", 735 | "files": [], 736 | "opam": { 737 | "name": "jbuilder", 738 | "version": "transition", 739 | "opam": 740 | "opam-version: \"1.2\"\nmaintainer: \"opensource@janestreet.com\"\nauthors: \"Jane Street Group, LLC \"\nlicense: \"MIT\"\nhomepage: \"https://github.com/ocaml/dune\"\nbug-reports: \"https://github.com/ocaml/dune/issues\"\ndepends: [\"dune\"]\npost-messages:\n \"Jbuilder has been renamed and the jbuilder package is now a transition package. Use the dune package instead.\"\ndev-repo: \"git+https://github.com/ocaml/dune.git\"", 741 | "override": { "dependencies": { "@opam/ocamlfind": "*" } } 742 | } 743 | }, 744 | "dependencies": [ 745 | "@esy-ocaml/substs@0.0.1", "@opam/dune@opam:1.0.1", 746 | "@opam/ocamlfind@opam:1.8.0" 747 | ] 748 | }, 749 | "@opam/fpath@opam:0.7.2": { 750 | "record": { 751 | "name": "@opam/fpath", 752 | "version": "opam:0.7.2", 753 | "source": [ 754 | "archive:https://opam.ocaml.org/archives/fpath.0.7.2+opam.tar.gz#md5:cbb85938dc7d5524682f64ef1fd134c4", 755 | "archive:http://erratique.ch/software/fpath/releases/fpath-0.7.2.tbz#md5:52c7ecb0bf180088336f3c645875fa41" 756 | ], 757 | "files": [], 758 | "opam": { 759 | "name": "fpath", 760 | "version": "0.7.2", 761 | "opam": 762 | "opam-version: \"1.2\"\nmaintainer: \"Daniel Bünzli \"\nauthors: \"Daniel Bünzli \"\nlicense: \"ISC\"\ntags: [\"file\" \"system\" \"path\" \"org:erratique\"]\nhomepage: \"http://erratique.ch/software/fpath\"\ndoc: \"http://erratique.ch/software/fpath/doc\"\nbug-reports: \"https://github.com/dbuenzli/fpath/issues\"\ndepends: [\n \"ocamlfind\" {build}\n \"ocamlbuild\" {build}\n \"topkg\" {build & >= \"0.9.0\"}\n \"result\"\n \"astring\"\n]\navailable: ocaml-version >= \"4.01.0\"\nbuild: [\"ocaml\" \"pkg/pkg.ml\" \"build\" \"--dev-pkg\" \"%{pinned}%\"]\ndev-repo: \"git+http://erratique.ch/repos/fpath.git\"", 763 | "override": null 764 | } 765 | }, 766 | "dependencies": [ 767 | "@esy-ocaml/substs@0.0.1", "@opam/astring@opam:0.8.3", 768 | "@opam/ocamlbuild@opam:0.12.0", "@opam/ocamlfind@opam:1.8.0", 769 | "@opam/result@opam:1.3", "@opam/topkg@opam:0.9.1" 770 | ] 771 | }, 772 | "@opam/fmt@opam:0.8.5": { 773 | "record": { 774 | "name": "@opam/fmt", 775 | "version": "opam:0.8.5", 776 | "source": [ 777 | "archive:https://opam.ocaml.org/archives/fmt.0.8.5+opam.tar.gz#md5:7d36eb6998bfbd93d497f5cd0b32ddfc", 778 | "archive:http://erratique.ch/software/fmt/releases/fmt-0.8.5.tbz#md5:77b64aa6f20f09de28f2405d6195f12c" 779 | ], 780 | "files": [], 781 | "opam": { 782 | "name": "fmt", 783 | "version": "0.8.5", 784 | "opam": 785 | "opam-version: \"1.2\"\nmaintainer: \"Daniel Bünzli \"\nauthors: [\"Daniel Bünzli \" \"Gabriel Radanne\"]\nlicense: \"ISC\"\ntags: [\"string\" \"format\" \"pretty-print\" \"org:erratique\"]\nhomepage: \"http://erratique.ch/software/fmt\"\ndoc: \"http://erratique.ch/software/fmt\"\nbug-reports: \"https://github.com/dbuenzli/fmt/issues\"\ndepends: [\n \"ocamlfind\" {build}\n \"ocamlbuild\" {build}\n \"topkg\" {build & >= \"0.9.0\"}\n \"result\"\n \"uchar\"\n]\ndepopts: [\"base-unix\" \"cmdliner\"]\nconflicts: [\n \"cmdliner\" {< \"0.9.8\"}\n]\navailable: ocaml-version >= \"4.01.0\"\nbuild: [\n \"ocaml\"\n \"pkg/pkg.ml\"\n \"build\"\n \"--dev-pkg\"\n \"%{pinned}%\"\n \"--with-base-unix\"\n \"%{base-unix:installed}%\"\n \"--with-cmdliner\"\n \"%{cmdliner:installed}%\"\n]\ndev-repo: \"git+http://erratique.ch/repos/fmt.git\"", 786 | "override": null 787 | } 788 | }, 789 | "dependencies": [ 790 | "@esy-ocaml/substs@0.0.1", "@opam/ocamlbuild@opam:0.12.0", 791 | "@opam/ocamlfind@opam:1.8.0", "@opam/result@opam:1.3", 792 | "@opam/topkg@opam:0.9.1", "@opam/uchar@opam:0.0.2" 793 | ] 794 | }, 795 | "@opam/easy-format@opam:1.3.1": { 796 | "record": { 797 | "name": "@opam/easy-format", 798 | "version": "opam:1.3.1", 799 | "source": [ 800 | "archive:https://opam.ocaml.org/archives/easy-format.1.3.1+opam.tar.gz#md5:6fa9fa55978e78690975f0663cb45a85", 801 | "archive:https://github.com/mjambon/easy-format/archive/v1.3.1.tar.gz#md5:4e163700fb88fdcd6b8976c3a216c8ea" 802 | ], 803 | "files": [], 804 | "opam": { 805 | "name": "easy-format", 806 | "version": "1.3.1", 807 | "opam": 808 | "opam-version: \"1.2\"\nmaintainer: \"martin@mjambon.com\"\nauthors: \"Martin Jambon\"\nhomepage: \"http://mjambon.com/easy-format.html\"\nbug-reports: \"https://github.com/mjambon/easy-format/issues\"\ndepends: [\n \"jbuilder\" {build}\n]\navailable: ocaml-version >= \"4.02.3\"\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\nrun-test: [\"jbuilder\" \"runtest\" \"-p\" name]\ndev-repo: \"git+https://github.com/mjambon/easy-format.git\"", 809 | "override": null 810 | } 811 | }, 812 | "dependencies": [ 813 | "@esy-ocaml/substs@0.0.1", "@opam/jbuilder@opam:transition" 814 | ] 815 | }, 816 | "@opam/dune@opam:1.0.1": { 817 | "record": { 818 | "name": "@opam/dune", 819 | "version": "opam:1.0.1", 820 | "source": [ 821 | "archive:https://opam.ocaml.org/archives/dune.1.0.1+opam.tar.gz#md5:bcfdd66662b5306c42ca8185deb39862", 822 | "archive:https://github.com/ocaml/dune/releases/download/1.0.1/dune-1.0.1.tbz#md5:7f6c56aa5a9043afb7b0dd313887c7c9" 823 | ], 824 | "files": [], 825 | "opam": { 826 | "name": "dune", 827 | "version": "1.0.1", 828 | "opam": 829 | "opam-version: \"1.2\"\nmaintainer: \"opensource@janestreet.com\"\nauthors: \"Jane Street Group, LLC \"\nlicense: \"MIT\"\nhomepage: \"https://github.com/ocaml/dune\"\nbug-reports: \"https://github.com/ocaml/dune/issues\"\nconflicts: [\n \"jbuilder\" {!= \"transition\"}\n]\navailable: ocaml-version >= \"4.02.3\"\nbuild: [\n [\"ocaml\" \"configure.ml\" \"--libdir\" lib]\n [\"ocaml\" \"bootstrap.ml\"]\n [\"./boot.exe\" \"--release\" \"--subst\"] {pinned}\n [\"./boot.exe\" \"--release\" \"-j\" jobs]\n]\ndev-repo: \"git+https://github.com/ocaml/dune.git\"", 830 | "override": { 831 | "build": [ 832 | [ "ocaml", "bootstrap.ml" ], 833 | [ "./boot.exe", "--release", "-j", "4" ] 834 | ] 835 | } 836 | } 837 | }, 838 | "dependencies": [ "@esy-ocaml/substs@0.0.1" ] 839 | }, 840 | "@opam/cppo@opam:1.6.4": { 841 | "record": { 842 | "name": "@opam/cppo", 843 | "version": "opam:1.6.4", 844 | "source": [ 845 | "archive:https://opam.ocaml.org/archives/cppo.1.6.4+opam.tar.gz#md5:c6651a3677048b442859d085138c2cc2", 846 | "archive:https://github.com/mjambon/cppo/archive/v1.6.4.tar.gz#md5:f7a4a6a0e83b76562b45db3a93ffd204" 847 | ], 848 | "files": [], 849 | "opam": { 850 | "name": "cppo", 851 | "version": "1.6.4", 852 | "opam": 853 | "opam-version: \"1.2\"\nmaintainer: \"martin@mjambon.com\"\nauthors: \"Martin Jambon\"\nlicense: \"BSD-3-Clause\"\nhomepage: \"https://github.com/mjambon/cppo\"\nbug-reports: \"https://github.com/mjambon/cppo/issues\"\ndepends: [\n \"jbuilder\" {build & >= \"1.0+beta17\"}\n \"base-bytes\"\n \"base-unix\"\n]\nbuild: [\n [\"jbuilder\" \"subst\" \"-p\" name] {pinned}\n [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\n]\nrun-test: [\"jbuilder\" \"runtest\" \"-p\" name]\ndev-repo: \"git+https://github.com/mjambon/cppo.git\"", 854 | "override": null 855 | } 856 | }, 857 | "dependencies": [ 858 | "@esy-ocaml/substs@0.0.1", "@opam/base-bytes@opam:base", 859 | "@opam/base-unix@opam:base", "@opam/jbuilder@opam:transition" 860 | ] 861 | }, 862 | "@opam/conf-which@opam:1": { 863 | "record": { 864 | "name": "@opam/conf-which", 865 | "version": "opam:1", 866 | "source": "no-source:", 867 | "files": [], 868 | "opam": { 869 | "name": "conf-which", 870 | "version": "1", 871 | "opam": 872 | "opam-version: \"1.2\"\nmaintainer: \"unixjunkie@sdf.org\"\nauthors: \"Carlo Wood\"\nlicense: \"GPL-2+\"\nhomepage: \"http://www.gnu.org/software/which/\"\nbug-reports: \"https://github.com/ocaml/opam-repository/issues\"\nbuild: [\"which\" \"which\"]\ndepexts: [\n [\"which\"] {\"centos\"}\n [\"which\"] {\"fedora\"}\n [\"which\"] {\"opensuse\"}\n [\"debianutils\"] {\"debian\"}\n [\"debianutils\"] {\"ubuntu\"}\n [\"which\"] {\"nixpkgs\"}\n [\"which\"] {\"archlinux\"}\n]\ndev-repo: \"git+https://github.com/ocaml/opam-repository.git\"", 873 | "override": null 874 | } 875 | }, 876 | "dependencies": [ "@esy-ocaml/substs@0.0.1" ] 877 | }, 878 | "@opam/conf-m4@opam:1": { 879 | "record": { 880 | "name": "@opam/conf-m4", 881 | "version": "opam:1", 882 | "source": "no-source:", 883 | "files": [], 884 | "opam": { 885 | "name": "conf-m4", 886 | "version": "1", 887 | "opam": 888 | "opam-version: \"1.2\"\nmaintainer: \"tim@gfxmonk.net\"\nlicense: \"GPL-3\"\nhomepage: \"http://www.gnu.org/software/m4/m4.html\"\nbug-reports: \"https://github.com/ocaml/opam-repository/issues\"\nbuild: [\"sh\" \"-exc\" \"echo | m4\"]\ndepexts: [\n [\"m4\"] {\"debian\"}\n [\"m4\"] {\"ubuntu\"}\n [\"m4\"] {\"fedora\"}\n [\"m4\"] {\"rhel\"}\n [\"m4\"] {\"centos\"}\n [\"m4\"] {\"alpine\"}\n [\"m4\"] {\"nixpkgs\"}\n [\"m4\"] {\"opensuse\"}\n [\"m4\"] {\"oraclelinux\"}\n [\"m4\"] {\"archlinux\"}\n]\ndev-repo: \"git+https://github.com/ocaml/opam-repository.git\"", 889 | "override": null 890 | } 891 | }, 892 | "dependencies": [ "@esy-ocaml/substs@0.0.1" ] 893 | }, 894 | "@opam/cmdliner@opam:1.0.2": { 895 | "record": { 896 | "name": "@opam/cmdliner", 897 | "version": "opam:1.0.2", 898 | "source": [ 899 | "archive:https://opam.ocaml.org/archives/cmdliner.1.0.2+opam.tar.gz#md5:b3f734417099fa5d9198bc927b12873f", 900 | "archive:http://erratique.ch/software/cmdliner/releases/cmdliner-1.0.2.tbz#md5:ab2f0130e88e8dcd723ac6154c98a881" 901 | ], 902 | "files": [], 903 | "opam": { 904 | "name": "cmdliner", 905 | "version": "1.0.2", 906 | "opam": 907 | "opam-version: \"1.2\"\nmaintainer: \"Daniel Bünzli \"\nauthors: \"Daniel Bünzli \"\nlicense: \"ISC\"\ntags: [\"cli\" \"system\" \"declarative\" \"org:erratique\"]\nhomepage: \"http://erratique.ch/software/cmdliner\"\ndoc: \"http://erratique.ch/software/cmdliner/doc/Cmdliner\"\nbug-reports: \"https://github.com/dbuenzli/cmdliner/issues\"\ndepends: [\n \"ocamlfind\" {build}\n \"ocamlbuild\" {build}\n \"topkg\" {build}\n \"result\"\n]\navailable: ocaml-version >= \"4.01.0\"\nbuild: [\"ocaml\" \"pkg/pkg.ml\" \"build\" \"--pinned\" \"%{pinned}%\"]\ndev-repo: \"git+http://erratique.ch/repos/cmdliner.git\"", 908 | "override": null 909 | } 910 | }, 911 | "dependencies": [ 912 | "@esy-ocaml/substs@0.0.1", "@opam/ocamlbuild@opam:0.12.0", 913 | "@opam/ocamlfind@opam:1.8.0", "@opam/result@opam:1.3", 914 | "@opam/topkg@opam:0.9.1" 915 | ] 916 | }, 917 | "@opam/biniou@opam:1.2.0": { 918 | "record": { 919 | "name": "@opam/biniou", 920 | "version": "opam:1.2.0", 921 | "source": [ 922 | "archive:https://opam.ocaml.org/archives/biniou.1.2.0+opam.tar.gz#md5:488e51fe3339b2b190dfa1db74dd7946", 923 | "archive:https://github.com/mjambon/biniou/archive/v1.2.0.tar.gz#md5:f3e92358e832ed94eaf23ce622ccc2f9" 924 | ], 925 | "files": [], 926 | "opam": { 927 | "name": "biniou", 928 | "version": "1.2.0", 929 | "opam": 930 | "opam-version: \"1.2\"\nmaintainer: \"martin@mjambon.com\"\nauthors: \"Martin Jambon\"\nlicense: \"BSD-3-Clause\"\nhomepage: \"https://github.com/mjambon/biniou\"\nbug-reports: \"https://github.com/mjambon/biniou/issues\"\ndepends: [\n \"conf-which\" {build}\n \"jbuilder\" {build & >= \"1.0+beta7\"}\n \"easy-format\"\n]\navailable: ocaml-version >= \"4.02.3\"\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\nrun-test: [\"jbuilder\" \"runtest\" \"-p\" name]\ndev-repo: \"git+https://github.com/mjambon/biniou.git\"", 931 | "override": null 932 | } 933 | }, 934 | "dependencies": [ 935 | "@esy-ocaml/substs@0.0.1", "@opam/conf-which@opam:1", 936 | "@opam/easy-format@opam:1.3.1", "@opam/jbuilder@opam:transition" 937 | ] 938 | }, 939 | "@opam/base-unix@opam:base": { 940 | "record": { 941 | "name": "@opam/base-unix", 942 | "version": "opam:base", 943 | "source": "no-source:", 944 | "files": [], 945 | "opam": { 946 | "name": "base-unix", 947 | "version": "base", 948 | "opam": 949 | "opam-version: \"1\"\nmaintainer: \"https://github.com/ocaml/opam-repository/issues\"", 950 | "override": null 951 | } 952 | }, 953 | "dependencies": [ "@esy-ocaml/substs@0.0.1" ] 954 | }, 955 | "@opam/base-bytes@opam:base": { 956 | "record": { 957 | "name": "@opam/base-bytes", 958 | "version": "opam:base", 959 | "source": "no-source:", 960 | "files": [], 961 | "opam": { 962 | "name": "base-bytes", 963 | "version": "base", 964 | "opam": 965 | "opam-version: \"1.2\"\nmaintainer: \" \"\nauthors: \" \"\nhomepage: \" \"\ndepends: [\n \"ocamlfind\" {>= \"1.5.3\"}\n]\navailable: ocaml-version >= \"4.02.0\"", 966 | "override": null 967 | } 968 | }, 969 | "dependencies": [ 970 | "@esy-ocaml/substs@0.0.1", "@opam/ocamlfind@opam:1.8.0" 971 | ] 972 | }, 973 | "@opam/base@opam:v0.11.1": { 974 | "record": { 975 | "name": "@opam/base", 976 | "version": "opam:v0.11.1", 977 | "source": [ 978 | "archive:https://opam.ocaml.org/archives/base.v0.11.1+opam.tar.gz#md5:c211940166b706df35bd47a8ffd4b89f", 979 | "archive:https://github.com/janestreet/base/releases/download/v0.11.1/base-v0.11.1.tbz#md5:e7e7dc5db3f1fea19d74a31bbd4ac621" 980 | ], 981 | "files": [], 982 | "opam": { 983 | "name": "base", 984 | "version": "v0.11.1", 985 | "opam": 986 | "opam-version: \"1.2\"\nmaintainer: \"opensource@janestreet.com\"\nauthors: \"Jane Street Group, LLC \"\nlicense: \"Apache-2.0\"\nhomepage: \"https://github.com/janestreet/base\"\nbug-reports: \"https://github.com/janestreet/base/issues\"\ndepends: [\n \"sexplib0\" {>= \"v0.11\" & < \"v0.12\"}\n \"jbuilder\" {build & >= \"1.0+beta18.1\"}\n]\ndepopts: [\"base-native-int63\"]\navailable: ocaml-version >= \"4.04.1\"\nbuild: [\"jbuilder\" \"build\" \"-p\" name \"-j\" jobs]\ndev-repo: \"git+https://github.com/janestreet/base.git\"", 987 | "override": null 988 | } 989 | }, 990 | "dependencies": [ 991 | "@esy-ocaml/substs@0.0.1", "@opam/jbuilder@opam:transition", 992 | "@opam/sexplib0@opam:v0.11.0" 993 | ] 994 | }, 995 | "@opam/astring@opam:0.8.3": { 996 | "record": { 997 | "name": "@opam/astring", 998 | "version": "opam:0.8.3", 999 | "source": [ 1000 | "archive:https://opam.ocaml.org/archives/astring.0.8.3+opam.tar.gz#md5:e2fe279530a6602caa413dba36889254", 1001 | "archive:http://erratique.ch/software/astring/releases/astring-0.8.3.tbz#md5:c5bf6352b9ac27fbeab342740f4fa870" 1002 | ], 1003 | "files": [], 1004 | "opam": { 1005 | "name": "astring", 1006 | "version": "0.8.3", 1007 | "opam": 1008 | "opam-version: \"1.2\"\nmaintainer: \"Daniel Bünzli \"\nauthors: \"Daniel Bünzli \"\nlicense: \"ISC\"\ntags: [\"string\" \"org:erratique\"]\nhomepage: \"http://erratique.ch/software/astring\"\ndoc: \"http://erratique.ch/software/astring/doc\"\nbug-reports: \"https://github.com/dbuenzli/astring/issues\"\ndepends: [\n \"ocamlfind\" {build}\n \"ocamlbuild\" {build}\n \"topkg\" {build}\n \"base-bytes\"\n]\navailable: ocaml-version >= \"4.01.0\"\nbuild: [\"ocaml\" \"pkg/pkg.ml\" \"build\" \"--pinned\" \"%{pinned}%\"]\ndev-repo: \"git+http://erratique.ch/repos/astring.git\"", 1009 | "override": null 1010 | } 1011 | }, 1012 | "dependencies": [ 1013 | "@esy-ocaml/substs@0.0.1", "@opam/base-bytes@opam:base", 1014 | "@opam/ocamlbuild@opam:0.12.0", "@opam/ocamlfind@opam:1.8.0", 1015 | "@opam/topkg@opam:0.9.1" 1016 | ] 1017 | }, 1018 | "@esy-ocaml/substs@0.0.1": { 1019 | "record": { 1020 | "name": "@esy-ocaml/substs", 1021 | "version": "0.0.1", 1022 | "source": 1023 | "archive:https://registry.npmjs.org/@esy-ocaml/substs/-/substs-0.0.1.tgz#sha1:59ebdbbaedcda123fc7ed8fb2b302b7d819e9a46", 1024 | "files": [], 1025 | "opam": null 1026 | }, 1027 | "dependencies": [] 1028 | }, 1029 | "@esy-ocaml/reason@3.3.0": { 1030 | "record": { 1031 | "name": "@esy-ocaml/reason", 1032 | "version": "3.3.0", 1033 | "source": 1034 | "archive:https://registry.npmjs.org/@esy-ocaml/reason/-/reason-3.3.0.tgz#sha1:8d282f5cc5c569b8b5ca5ef4203050d070febd5b", 1035 | "files": [], 1036 | "opam": null 1037 | }, 1038 | "dependencies": [ 1039 | "@esy-ocaml/esy-installer@0.0.0", "@esy-ocaml/substs@0.0.1", 1040 | "@opam/jbuilder@opam:transition", "@opam/menhir@opam:20171013", 1041 | "@opam/merlin-extend@opam:0.3", 1042 | "@opam/ocaml-migrate-parsetree@opam:1.0.11", 1043 | "@opam/ocamlfind@opam:1.8.0", "@opam/result@opam:1.3" 1044 | ] 1045 | }, 1046 | "@esy-ocaml/esy-installer@0.0.0": { 1047 | "record": { 1048 | "name": "@esy-ocaml/esy-installer", 1049 | "version": "0.0.0", 1050 | "source": 1051 | "archive:https://registry.npmjs.org/@esy-ocaml/esy-installer/-/esy-installer-0.0.0.tgz#sha1:6b0e2bd4ee43531ac74793fe55cfcc3aca197a66", 1052 | "files": [], 1053 | "opam": null 1054 | }, 1055 | "dependencies": [] 1056 | } 1057 | } 1058 | } -------------------------------------------------------------------------------- /lib.md: -------------------------------------------------------------------------------- 1 | # API Surface Draft 2 | This document is meant to spec out the API surface of the "standard" lib that we are adding to RRun. 3 | 4 | ## `Cmd` 5 | #### Description: 6 | Command line Tools for building and executing CLI's 7 | 8 | #### API: 9 | ```re 10 | 11 | ``` 12 | --- 13 | 14 | ## `Fs` 15 | #### Description: 16 | File System access and manipulation 17 | 18 | #### API: 19 | ```re 20 | 21 | ``` 22 | --- 23 | 24 | ## `Path` 25 | #### Description: 26 | Utilities for interacting with file and directory paths 27 | 28 | #### API: 29 | ```rei 30 | 31 | let basename: (~ext: string=?, string) => string; 32 | 33 | let delimeter: string; 34 | 35 | let sep: string; 36 | 37 | let dirname: string => string; 38 | 39 | let extname: string => string; 40 | 41 | type pathObject = { 42 | dir: option(string), 43 | root: option(string), 44 | base: option(string), 45 | name: option(string), 46 | ext: option(string) 47 | }; 48 | 49 | let format: pathObject => string; 50 | 51 | let isAbsolute: string => bool; 52 | 53 | let join: list(string) => string; 54 | 55 | let normalize: string => string; 56 | 57 | let parse: string => pathObject; 58 | 59 | let relative: (~from: string, ~_to: string) => string; 60 | 61 | let relativeFilePath: (~from: string, ~_to: string) => string; 62 | 63 | let resolve: list(string) => string; 64 | ``` 65 | --- 66 | 67 | ## `Os` 68 | #### Description: 69 | Unix/Windows system methods and properties 70 | 71 | #### API: 72 | ```rei 73 | 74 | ``` 75 | --- 76 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rrun", 3 | "version": "0.0.0", 4 | "description": "Reason/OCaml runtime", 5 | "author": "Andrey Popp { 20 | let ident = { 21 | let src = { 22 | let base = 23 | try ( 24 | { 25 | let data = Sys.getenv("RRUN_BASE"); 26 | data |> Sexplib.Sexp.of_string |> Source.t_of_sexp; 27 | } 28 | ) { 29 | | Not_found => 30 | let cwd = Sys.getcwd(); 31 | Source.Path(Fpath.(v(cwd) /\/ v(loc.loc_start.pos_fname))); 32 | }; 33 | 34 | BuildSystem.resolve(~base, spec); 35 | }; 36 | 37 | let id = Source.id(src); 38 | let ident = id |> Longident.parse |> Loc.make(~loc); 39 | dependencies := [{DepsMeta.id, spec, src}, ...dependencies^]; 40 | Deps.set(dependencies^); 41 | ident; 42 | }; 43 | 44 | Ast_builder.Default.pmod_ident(~loc, ident); 45 | }; 46 | 47 | let () = { 48 | let ext = { 49 | let pat1 = Ast_pattern.(estring(__)); 50 | let pat2 = { 51 | open Ast_pattern; 52 | let f = (_, v) => v; 53 | map2( 54 | ~f, 55 | pexp_attributes( 56 | many( 57 | attribute( 58 | string("reason.raw_literal"), 59 | single_expr_payload(estring(__)), 60 | ), 61 | ), 62 | estring(__), 63 | ), 64 | ); 65 | }; 66 | 67 | Extension.declare( 68 | name, 69 | Extension.Context.module_expr, 70 | Ast_pattern.(single_expr_payload(pat1 ||| pat2)), 71 | expand, 72 | ); 73 | }; 74 | 75 | Driver.register_transformation(name, ~extensions=[ext]); 76 | }; 77 | 78 | let () = Driver.standalone(); 79 | -------------------------------------------------------------------------------- /rrunlib/BuildSystem.re: -------------------------------------------------------------------------------- 1 | module Module: { 2 | type t = { 3 | id: string, 4 | kind, 5 | src: Source.t, 6 | obj_path: Fpath.t, 7 | exe_path: Fpath.t, 8 | src_path: Fpath.t, 9 | dep_path: Fpath.t, 10 | } 11 | and kind = 12 | | OCaml 13 | | Reason; 14 | 15 | let make: (~cfg: Config.t, Source.t) => t; 16 | let label: t => string; 17 | let orig_src_path: t => Fpath.t; 18 | } = { 19 | type t = { 20 | id: string, 21 | kind, 22 | src: Source.t, 23 | obj_path: Fpath.t, 24 | exe_path: Fpath.t, 25 | src_path: Fpath.t, 26 | dep_path: Fpath.t, 27 | } 28 | and kind = 29 | | OCaml 30 | | Reason; 31 | 32 | let label = m => 33 | switch (m.src) { 34 | | Path(path) => Fpath.to_string(path) 35 | | Https(uri) => Uri.to_string(uri) 36 | }; 37 | 38 | let make = (~cfg, src) => { 39 | let id = Source.id(src); 40 | let kind = 41 | switch (src) { 42 | | Path(path) => 43 | switch (Fpath.get_ext(path)) { 44 | | "re" 45 | | ".re" => Reason 46 | | "ml" 47 | | ".ml" => OCaml 48 | | _ => failwith("unknown module kind: " ++ Fpath.to_string(path)) 49 | } 50 | | Https(_) => OCaml 51 | }; 52 | 53 | let src_path = Fpath.(cfg.Config.store_path / id |> add_ext(".ml")); 54 | let dep_path = Fpath.(cfg.Config.store_path / id |> add_ext(".dep")); 55 | let exe_path = Fpath.(cfg.Config.store_path / id |> add_ext(".exe")); 56 | let obj_path = Fpath.(cfg.Config.store_path / id |> add_ext(".cmx")); 57 | {id, kind, src, obj_path, exe_path, src_path, dep_path}; 58 | }; 59 | 60 | let orig_src_path = m => 61 | switch (m.src) { 62 | | Path(path) => path 63 | | Https(_) => m.src_path 64 | }; 65 | }; 66 | 67 | type staleness = 68 | | New 69 | | Stale 70 | | Ready; 71 | 72 | let check_staleness = (~out_path, in_path) => 73 | switch%lwt (Fs.stat(out_path)) { 74 | | exception ([@implicit_arity] Unix.Unix_error(Unix.ENOENT, _, _)) => 75 | Lwt.return(New) 76 | | {Unix.st_mtime: out_mtime, _} => 77 | let%lwt {Unix.st_mtime: in_mtime, _} = Fs.stat(in_path); 78 | if (out_mtime < in_mtime) { 79 | Lwt.return(Stale); 80 | } else { 81 | Lwt.return(Ready); 82 | }; 83 | }; 84 | 85 | let fetch_to_store = (m: Module.t) => 86 | switch (m.src) { 87 | | Source.Path(path) => 88 | switch%lwt (check_staleness(~out_path=m.src_path, path)) { 89 | | Stale 90 | | New => 91 | let before = (oc, _ic) => 92 | Lwt_io.write(oc, "# 1 \"" ++ Fpath.to_string(path) ++ "\"\n"); 93 | 94 | %lwt 95 | { 96 | Fs.copy_file(~before, ~src_path=path, m.src_path); 97 | Lwt.return(); 98 | }; 99 | | Ready => Lwt.return() 100 | } 101 | | Source.Https(uri) => 102 | if%lwt (Fs.exists(m.src_path)) { 103 | Lwt.return(); 104 | } else { 105 | prerr_endline("[<- src] " ++ Module.label(m)); 106 | Process.run( 107 | Cmd.( 108 | v("curl") 109 | % "--silent" 110 | % "--fail" 111 | % "--location" 112 | % Uri.to_string(uri) 113 | % "--output" 114 | % p(m.src_path) 115 | ), 116 | ); 117 | } 118 | }; 119 | 120 | let extract_dependencies = (~cfg, m: Module.t) => { 121 | let path = Module.orig_src_path(m); 122 | switch%lwt (check_staleness(~out_path=m.dep_path, path)) { 123 | | Ready => DepsMeta.of_file(m.dep_path) 124 | | Stale 125 | | New => 126 | %lwt 127 | { 128 | fetch_to_store(m); 129 | let%lwt cmd = 130 | switch (m.kind) { 131 | | OCaml => 132 | Lwt.return( 133 | Cmd.( 134 | v("rrundep") 135 | % "-loc-filename" 136 | % p(path) 137 | % "-output-metadata" 138 | % p(m.dep_path) 139 | % "-impl" 140 | % p(m.src_path) 141 | ), 142 | ) 143 | | Reason => 144 | let ppPath = Fpath.(cfg.Config.store_path / (m.id ++ "__ml.ml")); 145 | %lwt 146 | { 147 | Fs.copy_file(~src_path=m.src_path, ppPath); 148 | %lwt 149 | { 150 | Process.run( 151 | Cmd.( 152 | v("refmt") 153 | % "--parse" 154 | % "re" 155 | % "--print" 156 | % "binary" 157 | % "--in-place" 158 | % p(ppPath) 159 | ), 160 | ); 161 | Lwt.return( 162 | Cmd.( 163 | v("rrundep") 164 | % "-loc-filename" 165 | % p(path) 166 | % "-output-metadata" 167 | % p(m.dep_path) 168 | % "-impl" 169 | % p(ppPath) 170 | ), 171 | ); 172 | }; 173 | }; 174 | }; 175 | 176 | let baseS = m.src |> Source.sexp_of_t |> Sexplib.Sexp.to_string; 177 | 178 | %lwt 179 | { 180 | Process.run(~env=[|"RRUN_BASE=" ++ baseS|], cmd); 181 | DepsMeta.of_file(m.dep_path); 182 | }; 183 | } 184 | }; 185 | }; 186 | 187 | let build = (~cfg, m: Module.t) => { 188 | let buildObj = (~force, m: Module.t) => { 189 | let work = () => { 190 | prerr_endline("[b obj] " ++ Module.label(m)); 191 | let cmd = { 192 | let rrundep_ppx = Cmd.(v("rrundep") % "-as-ppx"); 193 | let pp_refmt = 194 | Cmd.(v("refmt") % "--parse" % "re" % "--print" % "binary"); 195 | 196 | let default_args = [ 197 | "-verbose", 198 | "-short-paths", 199 | "-keep-locs", 200 | "-bin-annot", 201 | ]; 202 | 203 | let cmd = { 204 | let cmd = Cmd.(v("ocamlopt") |> add_args(default_args)); 205 | let cmd = Cmd.(cmd % "-c" % "-I" % p(cfg.Config.store_path)); 206 | let cmd = 207 | switch (m.kind) { 208 | | Reason => Cmd.(cmd % "-pp" % Cmd.to_string(pp_refmt)) 209 | | OCaml => cmd 210 | }; 211 | 212 | Cmd.(cmd % "-ppx" % Cmd.to_string(rrundep_ppx) % p(m.src_path)); 213 | }; 214 | 215 | cmd; 216 | }; 217 | 218 | let baseS = m.src |> Source.sexp_of_t |> Sexplib.Sexp.to_string; 219 | 220 | %lwt 221 | { 222 | Process.run(~env=[|"RRUN_BASE=" ++ baseS|], cmd); 223 | Lwt.return(true); 224 | }; 225 | }; 226 | 227 | switch%lwt ( 228 | check_staleness(~out_path=m.obj_path, Module.orig_src_path(m)) 229 | ) { 230 | | New 231 | | Stale => work() 232 | | Ready => 233 | if (force) { 234 | work(); 235 | } else { 236 | Lwt.return(false); 237 | } 238 | }; 239 | }; 240 | 241 | let buildExe = (~force, exe_path, objs) => { 242 | let work = () => { 243 | prerr_endline("[b exe] " ++ Module.label(m)); 244 | let cmd = { 245 | let cmd = 246 | Cmd.( 247 | v("ocamlopt") 248 | % "-short-paths" 249 | % "-keep-locs" 250 | % "-o" 251 | % p(exe_path) 252 | ); 253 | 254 | let f = (cmd, obj) => Cmd.(cmd % p(obj)); 255 | List.fold_left(f, cmd, objs); 256 | }; 257 | 258 | Process.run( 259 | ~env=[| 260 | "RRUN_FILENAME=" ++ Fpath.to_string(Module.orig_src_path(m)), 261 | |], 262 | cmd, 263 | ); 264 | }; 265 | 266 | switch%lwt ( 267 | check_staleness(~out_path=m.exe_path, Module.orig_src_path(m)) 268 | ) { 269 | | New 270 | | Stale => work() 271 | | Ready => 272 | if (force) { 273 | work(); 274 | } else { 275 | Lwt.return(); 276 | } 277 | }; 278 | }; 279 | 280 | let rec batchBuildObj = ((needRebuild, seen, objs), m) => { 281 | /* prerr_endline ("[->] " ^ Fpath.to_string m.path) ; */ 282 | let%lwt deps = extract_dependencies(~cfg, m); 283 | let%lwt (needRebuild, seen, objs) = { 284 | let buildDep = ((n, seen, objs), dep: DepsMeta.dep) => { 285 | let m = Module.make(~cfg, dep.src); 286 | let%lwt (nn, seen, objs) = 287 | batchBuildObj((needRebuild, seen, objs), m); 288 | Lwt.return((n || nn, seen, objs)); 289 | }; 290 | 291 | Lwt_list.fold_left_s(buildDep, (needRebuild, seen, objs), deps); 292 | }; 293 | 294 | let%lwt thisNeedRebuild = buildObj(~force=needRebuild, m); 295 | let thisWasRebuild = 296 | switch (Fpath.Map.find_opt(m.obj_path, seen)) { 297 | | Some(v) => v 298 | | None => false 299 | }; 300 | 301 | let%lwt needRebuild = 302 | Lwt.return(needRebuild || thisNeedRebuild || thisWasRebuild); 303 | 304 | let objs = 305 | if (Fpath.Map.mem(m.obj_path, seen)) { 306 | objs; 307 | } else { 308 | [m.obj_path, ...objs]; 309 | }; 310 | 311 | let seen = Fpath.Map.add(m.obj_path, thisNeedRebuild, seen); 312 | /* prerr_endline ("[<-] " ^ Fpath.to_string m.path) ; */ 313 | Lwt.return((needRebuild, seen, objs)); 314 | }; 315 | 316 | let%lwt (needRebuild, _seen, objs) = 317 | batchBuildObj((false, Fpath.Map.empty, []), m); 318 | 319 | %lwt 320 | { 321 | buildExe(~force=needRebuild, m.exe_path, List.rev(objs)); 322 | Lwt.return(m); 323 | }; 324 | }; 325 | 326 | let resolve = (~base=?, spec) => { 327 | let https_re = Str.regexp("^https:"); 328 | if (Str.string_match(https_re, spec, 0)) { 329 | Source.Https(Uri.of_string(spec)); 330 | } else { 331 | switch (base) { 332 | | Some(Source.Path(base_path)) => 333 | Source.Path(Fpath.(parent(base_path) /\/ v(spec) |> normalize)) 334 | | Some(Source.Https(uri)) => 335 | let base_path = Fpath.v(Uri.path(uri)); 336 | let path = Fpath.(parent(base_path) /\/ v(spec) |> normalize); 337 | let uri = Uri.with_path(uri, Fpath.to_string(path)); 338 | Source.Https(uri); 339 | | None => 340 | Source.Path(Fpath.(System.currentPath /\/ v(spec) |> normalize)) 341 | }; 342 | }; 343 | }; 344 | 345 | let build = (~cfg, root) => { 346 | let root = resolve(Fpath.to_string(root)); 347 | let root = Module.make(~cfg, root); 348 | let%lwt built = build(~cfg, root); 349 | Lwt.return(built.exe_path); 350 | }; 351 | -------------------------------------------------------------------------------- /rrunlib/BuildSystem.rei: -------------------------------------------------------------------------------- 1 | /** This implements build system */; 2 | 3 | /** Resolve source against base. */ 4 | let resolve: (~base: Source.t=?, string) => Source.t; 5 | 6 | /** Build program and return a path of the compiled executable. */ 7 | let build: (~cfg: Config.t, Fpath.t) => Lwt.t(Fpath.t); 8 | -------------------------------------------------------------------------------- /rrunlib/Cmd.re: -------------------------------------------------------------------------------- 1 | /* 2 | * Tool and a reversed list of args. 3 | * 4 | * We store args reversed so we allow an efficient append. 5 | * 6 | * XXX: It is important we do List.rev at the boundaries so we don't get a 7 | * reversed argument order. 8 | */ 9 | 10 | open Ppx_compare_lib.Builtin; 11 | 12 | [@deriving compare] 13 | type t = (string, list(string)); 14 | 15 | let equal = (a, b) => compare(a, b) == 0; 16 | 17 | let v = tool => (tool, []); 18 | 19 | let p = Fpath.to_string; 20 | 21 | let add_arg = (arg, (tool, args)) => { 22 | let args = [arg, ...args]; 23 | (tool, args); 24 | }; 25 | 26 | let add_args = (nargs, (tool, args)) => { 27 | let args = { 28 | let f = (args, arg) => [arg, ...args]; 29 | ListLabels.fold_left(~f, ~init=args, nargs); 30 | }; 31 | 32 | (tool, args); 33 | }; 34 | 35 | let (%) = ((tool, args), arg) => { 36 | let args = [arg, ...args]; 37 | (tool, args); 38 | }; 39 | 40 | let tool_and_args = ((tool, args)) => { 41 | let args = List.rev(args); 42 | (tool, args); 43 | }; 44 | 45 | let tool_and_line = ((tool, args)) => { 46 | let args = List.rev(args); 47 | (tool, Array.of_list([tool, ...args])); 48 | }; 49 | 50 | let tool = ((tool, _args)) => tool; 51 | 52 | let args = ((_tool, args)) => List.rev(args); 53 | 54 | let to_string = ((tool, args)) => { 55 | let tool = Filename.quote(tool); 56 | let args = List.rev(args); 57 | StringLabels.concat(~sep=" ", [tool, ...args]); 58 | }; 59 | 60 | let show = to_string; 61 | 62 | let pp = (ppf, (tool, args)) => 63 | switch (args) { 64 | | [] => Fmt.(pf(ppf, "%s", tool)) 65 | | args => 66 | let args = List.rev(args); 67 | let line = List.map(Filename.quote, [tool, ...args]); 68 | Fmt.(pf(ppf, "@[%a@]", list(~sep=sp, string), line)); 69 | }; 70 | -------------------------------------------------------------------------------- /rrunlib/Cmd.rei: -------------------------------------------------------------------------------- 1 | /** 2 | * Commands. 3 | * 4 | * Command is a tool and a list of arguments. 5 | */; 6 | 7 | type t; 8 | 9 | /** Produce a command supplying a tool. */ 10 | let v: string => t; 11 | 12 | /** Add a new argument to the command. */ 13 | let (%): (t, string) => t; 14 | 15 | /** Convert path to a string suitable to use with (%). */ 16 | let p: Fpath.t => string; 17 | 18 | /** 19 | * Add a new argument to the command. 20 | * 21 | * Same as (%) but with a flipped argument order. 22 | * Added for convenience usage with (|>). 23 | */ 24 | let add_arg: (string, t) => t; 25 | 26 | /** 27 | * Add a list of arguments to the command. 28 | * 29 | * it is convenient to use with (|>). 30 | */ 31 | let add_args: (list(string), t) => t; 32 | 33 | let tool_and_args: t => (string, list(string)); 34 | 35 | /** 36 | * Get a tuple of a tool and a list of argv suitable to be passed into 37 | * Lwt_process or Unix family of functions. 38 | */ 39 | let tool_and_line: t => (string, array(string)); 40 | 41 | let tool: t => string; 42 | 43 | let args: t => list(string); 44 | 45 | let pp: (Format.formatter, t) => unit; 46 | 47 | let show: t => string; 48 | 49 | let to_string: t => string; 50 | 51 | let equal: (t, t) => bool; 52 | 53 | let compare: (t, t) => int; 54 | -------------------------------------------------------------------------------- /rrunlib/Config.re: -------------------------------------------------------------------------------- 1 | type t = {store_path: Fpath.t}; 2 | 3 | let init = (~store_path=?, ()) => { 4 | let store_path = 5 | switch (store_path) { 6 | | Some(store_path) => store_path 7 | | None => Fpath.(System.homePath / ".rrun") 8 | }; 9 | 10 | let%lwt () = Fs.create_dir(store_path); 11 | Lwt.return({store_path: store_path}); 12 | }; 13 | -------------------------------------------------------------------------------- /rrunlib/Config.rei: -------------------------------------------------------------------------------- 1 | type t = pri {store_path: Fpath.t}; 2 | 3 | let init: (~store_path: Fpath.t=?, unit) => Lwt.t(t); 4 | -------------------------------------------------------------------------------- /rrunlib/DepsMeta.re: -------------------------------------------------------------------------------- 1 | open Sexplib.Conv; 2 | 3 | [@deriving sexp] 4 | type t = list(dep) 5 | and dep = { 6 | id: string, 7 | spec: string, 8 | src: Source.t, 9 | }; 10 | 11 | let of_file = path => { 12 | let%lwt data = Fs.read_file(path); 13 | if (String.length(data) == 0) { 14 | Lwt.return([]); 15 | } else { 16 | switch (Sexplib.Sexp.of_string(data)) { 17 | | Sexplib.Sexp.List([Sexplib.Sexp.Atom("deps"), deps]) => 18 | let items = t_of_sexp(deps); 19 | Lwt.return(items); 20 | | _ => raise(Invalid_argument("invalid dependency format")) 21 | }; 22 | }; 23 | }; -------------------------------------------------------------------------------- /rrunlib/DepsMeta.rei: -------------------------------------------------------------------------------- 1 | type dep = { 2 | id: string, 3 | spec: string, 4 | src: Source.t 5 | }; 6 | 7 | type t = list(dep); 8 | 9 | let sexp_of_t: t => Ppx_sexp_conv_lib.Sexp.t; 10 | 11 | let t_of_sexp: Ppx_sexp_conv_lib.Sexp.t => t; 12 | 13 | let of_file: Fpath.t => Lwt.t(t); 14 | -------------------------------------------------------------------------------- /rrunlib/Fs.re: -------------------------------------------------------------------------------- 1 | let stat = path => { 2 | let path = Fpath.to_string(path); 3 | Lwt_unix.stat(path); 4 | }; 5 | 6 | let exists = path => { 7 | let path = Fpath.to_string(path); 8 | switch%lwt (Lwt_unix.stat(path)) { 9 | | exception ([@implicit_arity] Unix.Unix_error(Unix.ENOENT, _, _)) => 10 | Lwt.return(false) 11 | | _ => Lwt.return(true) 12 | }; 13 | }; 14 | 15 | let copy_stats = (~stat, path) => { 16 | let chown = (path, uid, gid) => 17 | try%lwt (Lwt_unix.chown(path, uid, gid)) { 18 | | [@implicit_arity] Unix.Unix_error(Unix.EPERM, _, _) => Lwt.return() 19 | }; 20 | 21 | let path = Fpath.to_string(path); 22 | let%lwt () = Lwt_unix.utimes(path, stat.Unix.st_atime, stat.Unix.st_mtime); 23 | let%lwt () = Lwt_unix.chmod(path, stat.Unix.st_perm); 24 | let%lwt () = chown(path, stat.Unix.st_uid, stat.Unix.st_gid); 25 | Lwt.return(); 26 | }; 27 | 28 | let read_file = path => { 29 | let path = Fpath.to_string(path); 30 | Lwt_io.with_file(~mode=Lwt_io.Input, path, ic => Lwt_io.read(ic)); 31 | }; 32 | 33 | let copy_file = (~before=?, ~src_path, dst_path) => { 34 | let origPathS = Fpath.to_string(src_path); 35 | let destPathS = Fpath.to_string(dst_path); 36 | let chunkSize = 1024 * 1024 /* 1mb */; 37 | let%lwt stat = Lwt_unix.stat(origPathS); 38 | let copy = (ic, oc) => { 39 | let buffer = Bytes.create(chunkSize); 40 | let%lwt () = 41 | switch (before) { 42 | | Some(before) => before(oc, ic) 43 | | None => Lwt.return() 44 | }; 45 | 46 | let rec loop = () => 47 | switch%lwt (Lwt_io.read_into(ic, buffer, 0, chunkSize)) { 48 | | 0 => Lwt.return() 49 | | bytesRead => 50 | let%lwt () = Lwt_io.write_from_exactly(oc, buffer, 0, bytesRead); 51 | loop(); 52 | }; 53 | 54 | loop(); 55 | }; 56 | 57 | let%lwt () = 58 | Lwt_io.with_file( 59 | origPathS, ~flags=Lwt_unix.[O_RDONLY], ~mode=Lwt_io.Input, ic => 60 | Lwt_io.with_file( 61 | ~mode=Lwt_io.Output, 62 | ~flags=Lwt_unix.[O_WRONLY, O_CREAT, O_TRUNC], 63 | ~perm=stat.Unix.st_perm, 64 | destPathS, 65 | copy(ic), 66 | ) 67 | ); 68 | 69 | let%lwt () = copy_stats(~stat, dst_path); 70 | Lwt.return(); 71 | }; 72 | 73 | let create_dir = path => { 74 | let path = Fpath.to_string(path); 75 | try%lwt (Lwt_unix.mkdir(path, 0o755)) { 76 | | [@implicit_arity] Unix.Unix_error(Unix.EEXIST, _, _) => Lwt.return() 77 | }; 78 | }; -------------------------------------------------------------------------------- /rrunlib/Fs.rei: -------------------------------------------------------------------------------- 1 | /** Check if file or dir exists. */ 2 | let exists: Fpath.t => Lwt.t(bool); 3 | 4 | /** stat */ 5 | let stat: Fpath.t => Lwt.t(Unix.stats); 6 | 7 | /** Read file */ 8 | let read_file: Fpath.t => Lwt.t(string); 9 | 10 | /** Copy file */ 11 | let copy_file: 12 | ( 13 | ~before: (Lwt_io.channel(Lwt_io.output), Lwt_io.channel(Lwt_io.input)) => 14 | Lwt.t(unit) 15 | =?, 16 | ~src_path: Fpath.t, 17 | Fpath.t 18 | ) => 19 | Lwt.t(unit); 20 | 21 | /** Create directory */ 22 | let create_dir: Fpath.t => Lwt.t(unit); -------------------------------------------------------------------------------- /rrunlib/Path.re: -------------------------------------------------------------------------------- 1 | include Fpath; 2 | 3 | let t_of_sexp = sexp => { 4 | let v = Sexplib.Conv.string_of_sexp(sexp); 5 | Fpath.v(v); 6 | }; 7 | 8 | let sexp_of_t = v => { 9 | let v = to_string(v); 10 | Sexplib.Conv.sexp_of_string(v); 11 | }; 12 | -------------------------------------------------------------------------------- /rrunlib/Process.re: -------------------------------------------------------------------------------- 1 | let run = (~env=?, cmd: Cmd.t) => { 2 | let f = (p: Lwt_process.process_full) => { 3 | let%lwt stderr = 4 | Lwt.finalize( 5 | () => Lwt_io.read(p#stderr), 6 | () => Lwt_io.close(p#stderr), 7 | ); 8 | 9 | let%lwt stdout = 10 | Lwt.finalize( 11 | () => Lwt_io.read(p#stdout), 12 | () => Lwt_io.close(p#stdout), 13 | ); 14 | 15 | switch%lwt (p#status) { 16 | | Unix.WEXITED(0) => Lwt.return() 17 | | Unix.WEXITED(_) => 18 | Format.printf( 19 | "command failed: %a@\n%s@\n%s", 20 | Cmd.pp, 21 | cmd, 22 | stdout, 23 | stderr, 24 | ); 25 | failwith("command failed"); 26 | | _ => failwith("error running subprocess") 27 | }; 28 | }; 29 | 30 | let cmd = Cmd.tool_and_line(cmd); 31 | let env = 32 | switch (env) { 33 | | Some(env) => Some(Array.append(Unix.environment(), env)) 34 | | None => None 35 | }; 36 | 37 | Lwt_process.with_process_full(~env?, cmd, f); 38 | }; 39 | -------------------------------------------------------------------------------- /rrunlib/Process.rei: -------------------------------------------------------------------------------- 1 | let run: (~env: array(string)=?, Cmd.t) => Lwt.t(unit); -------------------------------------------------------------------------------- /rrunlib/Source.re: -------------------------------------------------------------------------------- 1 | [@deriving sexp] 2 | type t = 3 | | Path(Path.t) 4 | | Https(Uri.t); 5 | 6 | let safe_string = spec => { 7 | let out = Buffer.create(String.length(spec)); 8 | String.iter( 9 | fun 10 | | '.' => Buffer.add_string(out, "S_DT_") 11 | | '/' => Buffer.add_string(out, "S_SL_") 12 | | '@' => Buffer.add_string(out, "S_AT_") 13 | | '_' => Buffer.add_string(out, "S_UN_") 14 | | '-' => Buffer.add_string(out, "S_DH_") 15 | | ' ' => Buffer.add_string(out, "S_SP_") 16 | | ':' => Buffer.add_string(out, "S_CL_") 17 | | ';' => Buffer.add_string(out, "S_SC_") 18 | | c => Buffer.add_char(out, c), 19 | spec, 20 | ); 21 | Buffer.contents(out); 22 | }; 23 | 24 | let id = 25 | fun 26 | | Path(path) => "U" ++ safe_string(Path.to_string(path)) 27 | | Https(url) => "M" ++ safe_string(Uri.to_string(url)); 28 | -------------------------------------------------------------------------------- /rrunlib/Source.rei: -------------------------------------------------------------------------------- 1 | type t = 2 | | Path(Path.t) 3 | | Https(Uri.t); 4 | 5 | let id: t => string; 6 | 7 | let sexp_of_t: t => Ppx_sexp_conv_lib.Sexp.t; 8 | 9 | let t_of_sexp: Ppx_sexp_conv_lib.Sexp.t => t; 10 | -------------------------------------------------------------------------------- /rrunlib/System.re: -------------------------------------------------------------------------------- 1 | let homePath = 2 | switch (Sys.getenv_opt("HOME")) { 3 | | Some(path) => Fpath.v(path) 4 | | None => Fpath.v(Unix.(getpwnam("username")).pw_dir) 5 | }; 6 | 7 | let currentPath = Fpath.(v(Sys.getcwd())); 8 | -------------------------------------------------------------------------------- /rrunlib/System.rei: -------------------------------------------------------------------------------- 1 | let homePath: Fpath.t; 2 | 3 | let currentPath: Fpath.t; 4 | -------------------------------------------------------------------------------- /rrunlib/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name rrun) 3 | (public_name rrun) 4 | (preprocess (pps lwt_ppx ppx_sexp_conv ppx_compare)) 5 | (libraries lwt lwt.unix cmdliner fpath fmt sexplib str uri)) 6 | --------------------------------------------------------------------------------