From 3c16ff7244b9302ef1b4fa8c18e2305dc8df7be0 Mon Sep 17 00:00:00 2001 From: Thibaut Mattio Date: Tue, 8 Jun 2021 14:36:37 +0200 Subject: [PATCH] Import OCaml Platform tools (#34) --- data/tools.yml | 208 ++++++++++++++++++ dune | 2 - package-lock.json | 34 +-- package.json | 10 +- src/ood-preview/asset/main.css | 102 +++++++++ src/ood-preview/dune | 8 - .../lib/ood_preview/ood_preview.ml | 1 + src/ood-preview/lib/ood_preview/tool.ml | 77 +++++++ .../ood_preview_web/handlers/page_handler.ml | 5 + .../lib/ood_preview_web/navigation.ml | 1 + src/ood-preview/lib/ood_preview_web/router.ml | 1 + .../lib/ood_preview_web/templates/dune | 6 + .../templates/platform_template.eml | 133 +++++++++++ src/ood/tools.ml | 29 +++ 14 files changed, 585 insertions(+), 32 deletions(-) create mode 100644 data/tools.yml delete mode 100644 src/ood-preview/dune create mode 100644 src/ood-preview/lib/ood_preview/tool.ml create mode 100644 src/ood-preview/lib/ood_preview_web/templates/platform_template.eml create mode 100644 src/ood/tools.ml diff --git a/data/tools.yml b/data/tools.yml new file mode 100644 index 000000000..f755b6db4 --- /dev/null +++ b/data/tools.yml @@ -0,0 +1,208 @@ +tools: + + - name: Bun + source: https://github.com/yomimono/ocaml-bun + license: MIT + synopsis: Simple management of afl-fuzz processes + description: > + A wrapper for OCaml processes using afl-fuzz, intended for easy use in CI environments. + lifecycle: incubate + + - name: Mdx + source: https://github.com/realworldocaml/mdx + license: ISC + synopsis: Executable code blocks inside markdown files + description: > + `ocaml-mdx` allows to execute code blocks inside markdown files. + There are (currently) two sub-commands, corresponding + to two modes of operations: pre-processing (`ocaml-mdx pp`) + and tests (`ocaml-mdx test`). + + The pre-processor mode allows to mix documentation and code, + and to practice "literate programming" using markdown and OCaml. + + The test mode allows to ensure that shell scripts and OCaml fragments + in the documentation always stays up-to-date. + + `ocaml-mdx` is released as two binaries called `ocaml-mdx` and `mdx` which are + the same, mdx being the deprecate name, kept for now for compatibility. + lifecycle: incubate + + - name: OCamlFormat + source: https://github.com/ocaml-ppx/ocamlformat + license: MIT + synopsis: Auto-formatter for OCaml code + description: > + OCamlFormat is a tool to automatically format OCaml code in a uniform style. + lifecycle: incubate + + - name: Dune-release + source: https://github.com/ocamllabs/dune-release + license: ISC + synopsis: Release dune packages in opam + description: > + `dune-release` is a tool to streamline the release of Dune packages in + [opam](https://opam.ocaml.org). It supports projects built + with [Dune](https://github.com/ocaml/dune) and hosted on + [GitHub](https://github.com). + lifecycle: incubate + + - name: OCaml LSP + source: https://github.com/ocaml/ocaml-lsp + license: ISC + synopsis: LSP Server for OCaml + description: > + An LSP server for OCaml. + lifecycle: incubate + + - name: Merlin + source: https://github.com/ocaml/merlin + license: MIT + synopsis: Editor helper, provides completion, typing and source browsing in Vim and Emacs + description: > + Merlin is an assistant for editing OCaml code. It aims to provide the features available in modern IDEs: error reporting, auto completion, source browsing and much more. + lifecycle: active + + - name: ppxlib + source: https://github.com/ocaml-ppx/ppxlib + license: MIT + synopsis: Standard library for ppx rewriters + description: > + Ppxlib is the standard library for ppx rewriters and other programs + that manipulate the in-memory reprensation of OCaml programs, a.k.a + the "Parsetree". + + It also comes bundled with two ppx rewriters that are commonly used to + write tools that manipulate and/or generate Parsetree values; + `ppxlib.metaquot` which allows to construct Parsetree values using the + OCaml syntax directly and `ppxlib.traverse` which provides various + ways of automatically traversing values of a given type, in particular + allowing to inject a complex structured value into generated code. + lifecycle: active + + - name: opam-publish + source: https://github.com/ocaml-opam/opam-publish + license: LGPLv2 + synopsis: A tool to ease contributions to opam repositories + description: > + opam-publish automates publishing packages to package repositories: it checks that the + opam file is complete using `opam lint`, verifies and adds the archive URL and its + checksum and files a GitHub pull request for merging it. + lifecycle: active + + - name: utop + source: https://github.com/ocaml-community/utop + license: 3 Clause BSD + synopsis: Universal toplevel for OCaml + description: > + utop is an improved toplevel (i.e., Read-Eval-Print Loop or REPL) for + OCaml. It can run in a terminal or in Emacs. It supports line + edition, history, real-time and context sensitive completion, colors, + and more. It integrates with the Tuareg mode in Emacs. + lifecycle: active + + - name: Dune + source: https://github.com/ocaml/dune + license: MIT + synopsis: Fast, portable, and opinionated build system + description: > + dune is a build system that was designed to simplify the release of + Jane Street packages. It reads metadata from "dune" files following a + very simple s-expression syntax. + + dune is fast, has very low-overhead, and supports parallel builds on + all platforms. It has no system dependencies; all you need to build + dune or packages using dune is OCaml. You don't need make or bash + as long as the packages themselves don't use bash explicitly. + + dune supports multi-package development by simply dropping multiple + repositories into the same directory. + + It also supports multi-context builds, such as building against + several opam roots/switches simultaneously. This helps maintaining + packages across several versions of OCaml and gives cross-compilation + for free. + lifecycle: active + + + - name: omp + source: https://github.com/ocaml-ppx/ocaml-migrate-parsetree + license: LGPLv2 + synopsis: Convert OCaml parsetrees between different versions + description: > + Convert OCaml parsetrees between different versions + + This library converts parsetrees, outcometree and ast mappers between + different OCaml versions. High-level functions help making PPX + rewriters independent of a compiler version. + lifecycle: sustain + + - name: ocamlbuild + source: https://github.com/ocaml/ocamlbuild + license: LGPLv2 + synopsis: OCamlbuild is a build system with builtin rules to easily build most OCaml projects + description: "" + lifecycle: sustain + + - name: ocamlfind + source: https://github.com/ocaml/ocamlfind + license: MIT + synopsis: A library manager for OCaml + description: > + Findlib is a library manager for OCaml. It provides a convention how + to store libraries, and a file format ("META") to describe the + properties of libraries. There is also a tool (ocamlfind) for + interpreting the META files, so that it is very easy to use libraries + in programs and scripts. + lifecycle: sustain + + - name: ocp-indent + source: https://github.com/OCamlPro/ocp-indent + license: LGPLv2 + synopsis: A simple tool to indent OCaml programs + description: > + Ocp-indent is based on an approximate, tolerant OCaml parser and a simple stack + machine ; this is much faster and more reliable than using regexps. Presets and + configuration options available, with the possibility to set them project-wide. + Supports most common syntax extensions, and extensible for others. + + Includes: + - An indentor program, callable from the command-line or from within editors + - Bindings for popular editors + - A library that can be directly used by editor writers, or just for + fault-tolerant/approximate parsing. + lifecycle: sustain + + - name: oasis + source: https://github.com/ocaml/oasis + license: LGPLv2 + synopsis: Tooling for building OCaml libraries and applications + description: > + OASIS generates a full configure, build and install system for your application. It starts with a simple _oasis file at the toplevel of your project and creates everything required. + + OASIS leverages existing OCaml tooling to perform most of it's work. In fact, it might be more appropriate to think of it as simply the glue that binds these other subsystems together and coordinates the work that they do. It should support the following tools: + + - OCamlbuild + - OMake + - OCamlMakefile (todo), + - ocaml-autoconf (todo) + + It also features a do-it-yourself command line invocation and an internal configure/install scheme. Libraries are managed through findlib. It has been tested on GNU Linux and Windows. + + It also allows to have standard entry points and description. It helps to integrates your libraries and software with third parties tools like OPAM. + lifecycle: deprecate + + - name: camlp4 + source: https://github.com/camlp4/camlp4 + license: LGPLv2 + synopsis: Camlp4 is a system for writing extensible parsers for programming languages + description: > + It provides a set of OCaml libraries that are used to define grammars as well + as loadable syntax extensions of such grammars. Camlp4 stands for Caml + Preprocessor and Pretty-Printer and one of its most important applications is + the definition of domain-specific extensions of the syntax of OCaml. + + Camlp4 was part of the official OCaml distribution until its version 4.01.0. + Since then it has been replaced by a simpler system which is easier to maintain + and to learn: ppx rewriters and extension points. + lifecycle: deprecate diff --git a/dune b/dune index 48ae4ee67..9721a3568 100644 --- a/dune +++ b/dune @@ -6,5 +6,3 @@ (with-stdout-to %{targets} (run %{bin:ood-cli} config)))) - -(data_only_dirs node_modules) diff --git a/package-lock.json b/package-lock.json index 8ff61c783..77160b8e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,28 +14,28 @@ } }, "@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { - "@nodelib/fs.stat": "2.0.4", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true }, "@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz", + "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==", "dev": true, "requires": { - "@nodelib/fs.scandir": "2.1.4", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, @@ -46,9 +46,9 @@ "dev": true }, "@tailwindcss/forms": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.3.2.tgz", - "integrity": "sha512-aj2/rJsGb2whAZ/BQWHWWQRSbhH0r/l1ozOByiv+ZNjBD84GMvb5dhAyfpeasFky+EJrAwX5eaqft8NQMZFWvA==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.3.3.tgz", + "integrity": "sha512-U8Fi/gq4mSuaLyLtFISwuDYzPB73YzgozjxOIHsK6NXgg/IWD1FLaHbFlWmurAMyy98O+ao74ksdQefsquBV1Q==", "dev": true, "requires": { "mini-svg-data-uri": "^1.2.3" @@ -1008,9 +1008,9 @@ } }, "tailwindcss": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-2.1.2.tgz", - "integrity": "sha512-T5t+wwd+/hsOyRw2HJuFuv0LTUm3MUdHm2DJ94GPVgzqwPPFa9XxX0KlwLWupUuiOUj6uiKURCzYPHFcuPch/w==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-2.1.4.tgz", + "integrity": "sha512-fh1KImDLg6se/Suaelju/5oFbqq1b0ntagmGLu0aG9LlnNPGHgO1n/4E57CbKcCtyz/VYnvVXUiWmfyfBBZQ6g==", "dev": true, "requires": { "@fullhuman/postcss-purgecss": "^3.1.3", diff --git a/package.json b/package.json index 35e398bf2..07c1837e6 100644 --- a/package.json +++ b/package.json @@ -15,10 +15,10 @@ "bs-platform": "9.0.2" }, "devDependencies": { - "@tailwindcss/aspect-ratio": "^0.2.0", - "@tailwindcss/forms": "^0.3.2", - "@tailwindcss/typography": "^0.4.0", - "autoprefixer": "^10.2.5", - "tailwindcss": "^2.1.2" + "@tailwindcss/aspect-ratio": "^0.2.1", + "@tailwindcss/forms": "^0.3.3", + "@tailwindcss/typography": "^0.4.1", + "autoprefixer": "^10.2.6", + "tailwindcss": "^2.1.4" } } diff --git a/src/ood-preview/asset/main.css b/src/ood-preview/asset/main.css index a5428be68..99b904fc5 100644 --- a/src/ood-preview/asset/main.css +++ b/src/ood-preview/asset/main.css @@ -1272,6 +1272,12 @@ select { } .top-0 { top: 0px; +} + .top-7 { + top: 1.75rem; +} + .left-7 { + left: 1.75rem; } .z-10 { z-index: 10; @@ -1319,6 +1325,18 @@ select { } .ml-4 { margin-left: 1rem; +} + .-mb-8 { + margin-bottom: -2rem; +} + .-ml-px { + margin-left: -1px; +} + .mt-0\.5 { + margin-top: 0.125rem; +} + .mt-0 { + margin-top: 0px; } .mt-8 { margin-top: 2rem; @@ -1337,6 +1355,9 @@ select { } .table { display: table; +} + .flow-root { + display: flow-root; } .grid { display: grid; @@ -1355,6 +1376,12 @@ select { } .h-10 { height: 2.5rem; +} + .h-full { + height: 100%; +} + .h-14 { + height: 3.5rem; } .w-5 { width: 1.25rem; @@ -1370,9 +1397,21 @@ select { } .w-10 { width: 2.5rem; +} + .w-0\.5 { + width: 0.125rem; +} + .w-0 { + width: 0px; +} + .w-14 { + width: 3.5rem; } .min-w-full { min-width: 100%; +} + .min-w-0 { + min-width: 0px; } .max-w-prose { max-width: 65ch; @@ -1394,12 +1433,18 @@ select { } .max-w-none { max-width: none; +} + .max-w-6xl { + max-width: 72rem; } .max-w-2xl { max-width: 42rem; } .max-w-full { max-width: 100%; +} + .flex-1 { + flex: 1 1 0%; } .flex-shrink-0 { flex-shrink: 0; @@ -1452,6 +1497,9 @@ select { } .items-center { align-items: center; +} + .items-start { + align-items: flex-start; } .justify-between { justify-content: space-between; @@ -1483,6 +1531,11 @@ select { --tw-space-x-reverse: 0; margin-right: calc(2.5rem * var(--tw-space-x-reverse)); margin-left: calc(2.5rem * calc(1 - var(--tw-space-x-reverse))); +} + .space-x-3 > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(0.75rem * var(--tw-space-x-reverse)); + margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse))); } .space-y-1 > :not([hidden]) ~ :not([hidden]) { --tw-space-y-reverse: 0; @@ -1570,6 +1623,22 @@ select { .bg-gray-50 { --tw-bg-opacity: 1; background-color: rgba(249, 250, 251, var(--tw-bg-opacity)); +} + .bg-blue-400 { + --tw-bg-opacity: 1; + background-color: rgba(96, 165, 250, var(--tw-bg-opacity)); +} + .bg-green-400 { + --tw-bg-opacity: 1; + background-color: rgba(52, 211, 153, var(--tw-bg-opacity)); +} + .bg-pink-400 { + --tw-bg-opacity: 1; + background-color: rgba(244, 114, 182, var(--tw-bg-opacity)); +} + .bg-red-400 { + --tw-bg-opacity: 1; + background-color: rgba(248, 113, 113, var(--tw-bg-opacity)); } .bg-opacity-50 { --tw-bg-opacity: 0.5; @@ -1742,6 +1811,14 @@ select { .text-green-800 { --tw-text-opacity: 1; color: rgba(6, 95, 70, var(--tw-text-opacity)); +} + .text-orangedark { + --tw-text-opacity: 1; + color: rgba(237, 113, 9, var(--tw-text-opacity)); +} + .text-gray-700 { + --tw-text-opacity: 1; + color: rgba(55, 65, 81, var(--tw-text-opacity)); } .antialiased { -webkit-font-smoothing: antialiased; @@ -1765,10 +1842,19 @@ select { --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} + .ring-8 { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(8px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); } .ring-black { --tw-ring-opacity: 1; --tw-ring-color: rgba(0, 0, 0, var(--tw-ring-opacity)); +} + .ring-white { + --tw-ring-opacity: 1; + --tw-ring-color: rgba(255, 255, 255, var(--tw-ring-opacity)); } .ring-opacity-5 { --tw-ring-opacity: 0.05; @@ -1974,6 +2060,10 @@ select { border-radius: 0.5rem; } + .sm\:rounded-md { + border-radius: 0.375rem; + } + .sm\:p-8 { padding: 2rem; } @@ -2018,6 +2108,10 @@ select { display: flex; } + .md\:grid { + display: grid; + } + .md\:hidden { display: none; } @@ -2030,6 +2124,10 @@ select { grid-template-columns: repeat(3, minmax(0, 1fr)); } + .md\:grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + .md\:items-center { align-items: center; } @@ -2042,6 +2140,10 @@ select { justify-content: space-between; } + .md\:gap-4 { + gap: 1rem; + } + .md\:space-x-10 > :not([hidden]) ~ :not([hidden]) { --tw-space-x-reverse: 0; margin-right: calc(2.5rem * var(--tw-space-x-reverse)); diff --git a/src/ood-preview/dune b/src/ood-preview/dune deleted file mode 100644 index e61a3dd37..000000000 --- a/src/ood-preview/dune +++ /dev/null @@ -1,8 +0,0 @@ -(env - (dev - (flags - (:standard -w +A-48-42-44 -warn-error +A-3)))) - -; Do not include node_modules in the build - -(data_only_dirs node_modules) diff --git a/src/ood-preview/lib/ood_preview/ood_preview.ml b/src/ood-preview/lib/ood_preview/ood_preview.ml index 26c7c8ffc..560c2b342 100644 --- a/src/ood-preview/lib/ood_preview/ood_preview.ml +++ b/src/ood-preview/lib/ood_preview/ood_preview.ml @@ -7,3 +7,4 @@ module Video = Video module Success_story = Success_story module Industrial_user = Industrial_user module Tutorial = Tutorial +module Tool = Tool diff --git a/src/ood-preview/lib/ood_preview/tool.ml b/src/ood-preview/lib/ood_preview/tool.ml new file mode 100644 index 000000000..67a0c698f --- /dev/null +++ b/src/ood-preview/lib/ood_preview/tool.ml @@ -0,0 +1,77 @@ +type metadata = + { name : string + ; source : string + ; license : string + ; synopsis : string + ; description : string + ; lifecycle : string + } +[@@deriving yaml] + +type lifecycle = + [ `Incubate + | `Active + | `Sustain + | `Deprecate + ] + +type t = Ood.Tools.Tool.t = + { name : string + ; source : string + ; license : string + ; synopsis : string + ; description : string + ; lifecycle : lifecycle + } + +let decode s = + let yaml = Utils.decode_or_raise Yaml.of_string s in + match yaml with + | `O [ ("tools", `A xs) ] -> + List.map + (fun x -> + try + let (metadata : metadata) = + Utils.decode_or_raise metadata_of_yaml x + in + let lifecycle = + match Ood.Tools.Lifecycle.of_string metadata.lifecycle with + | Ok x -> + x + | Error (`Msg err) -> + raise (Exn.Decode_error err) + in + let description = Omd.of_string metadata.description |> Omd.to_html in + ({ name = metadata.name + ; source = metadata.source + ; license = metadata.license + ; synopsis = metadata.synopsis + ; description + ; lifecycle + } + : t) + with + | e -> + print_endline (Yaml.to_string x |> Result.get_ok); + raise e) + xs + | _ -> + raise (Exn.Decode_error "expected a list of tools") + +let all () = + let content = Data.read "tools.yml" |> Option.get in + decode content + +let get_by_lifecycle lc = List.filter (fun (x : t) -> x.lifecycle = lc) (all ()) + +let get_incubate () = get_by_lifecycle `Incubate + +let get_active () = get_by_lifecycle `Active + +let get_sustain () = get_by_lifecycle `Sustain + +let get_deprecate () = get_by_lifecycle `Deprecate + +let slug (t : t) = Utils.slugify t.name + +let get_by_slug id = all () |> List.find_opt (fun video -> slug video = id) diff --git a/src/ood-preview/lib/ood_preview_web/handlers/page_handler.ml b/src/ood-preview/lib/ood_preview_web/handlers/page_handler.ml index 411eedee6..06af6f06c 100644 --- a/src/ood-preview/lib/ood_preview_web/handlers/page_handler.ml +++ b/src/ood-preview/lib/ood_preview_web/handlers/page_handler.ml @@ -59,3 +59,8 @@ let tutorials req = let first = Ood_preview.Tutorial.all () |> List.hd in let slug = Ood_preview.Tutorial.slug first in Dream.redirect req ("/tutorials/" ^ slug) + +let tools _req = + let tools = Ood_preview.Tool.all () in + Layout_template.render ~title:"Tools" (Platform_template.render tools) + |> Dream.html diff --git a/src/ood-preview/lib/ood_preview_web/navigation.ml b/src/ood-preview/lib/ood_preview_web/navigation.ml index acea25022..c2a23ff1a 100644 --- a/src/ood-preview/lib/ood_preview_web/navigation.ml +++ b/src/ood-preview/lib/ood_preview_web/navigation.ml @@ -31,6 +31,7 @@ let t = ; { label = "Events"; url = "/events"; icon = ""; text = "" } ; { label = "Videos"; url = "/videos"; icon = ""; text = "" } ; { label = "Tutorials"; url = "/tutorials"; icon = ""; text = "" } + ; { label = "Platform"; url = "/tools"; icon = ""; text = "" } ] } ] diff --git a/src/ood-preview/lib/ood_preview_web/router.ml b/src/ood-preview/lib/ood_preview_web/router.ml index c00f11281..b9a42acef 100644 --- a/src/ood-preview/lib/ood_preview_web/router.ml +++ b/src/ood-preview/lib/ood_preview_web/router.ml @@ -21,6 +21,7 @@ let routes = ; Dream.get "/books" Page_handler.books ; Dream.get "/events" Page_handler.events ; Dream.get "/videos" Page_handler.videos + ; Dream.get "/tools" Page_handler.tools ; Dream.get "/tutorials" Page_handler.tutorials ; Dream.get "/tutorials/:id" Page_handler.tutorial ; Dream.get "/assets/**" (Dream.static ~loader "") diff --git a/src/ood-preview/lib/ood_preview_web/templates/dune b/src/ood-preview/lib/ood_preview_web/templates/dune index a1402524d..9b6a5458a 100644 --- a/src/ood-preview/lib/ood_preview_web/templates/dune +++ b/src/ood-preview/lib/ood_preview_web/templates/dune @@ -63,3 +63,9 @@ (deps videos_template.eml) (action (run %{bin:dream_eml} %{deps} --workspace %{workspace_root}))) + +(rule + (targets platform_template.ml) + (deps platform_template.eml) + (action + (run %{bin:dream_eml} %{deps} --workspace %{workspace_root}))) diff --git a/src/ood-preview/lib/ood_preview_web/templates/platform_template.eml b/src/ood-preview/lib/ood_preview_web/templates/platform_template.eml new file mode 100644 index 000000000..04cd324bb --- /dev/null +++ b/src/ood-preview/lib/ood_preview_web/templates/platform_template.eml @@ -0,0 +1,133 @@ +[@@@ocaml.warning "-40"] + +let render_tool (tool : Ood_preview.Tool.t) = + let open Ood_preview.Tool in +
  • +
    +
    +
    +

    <%s tool.name %>

    +

    + <%s tool.synopsis %> +

    +
    +
    +
    +
  • + +let render tools = + let incubate = List.filter (fun (x : Ood_preview.Tool.t) -> x.lifecycle = `Incubate) tools in + let active = List.filter (fun (x : Ood_preview.Tool.t) -> x.lifecycle = `Active) tools in + let sustain = List.filter (fun (x : Ood_preview.Tool.t) -> x.lifecycle = `Sustain) tools in + let deprecate = List.filter (fun (x : Ood_preview.Tool.t) -> x.lifecycle = `Deprecate) tools in + <%s! Header_section_template.render ~subtitle:"The OCaml Platform represents the best way for developers, both new and old, to write software in OCaml. It combines the core OCaml compiler with a coherent set of tools, documentation, libraries and testing resources." "OCaml Platform" %> +
    +
    +
    +
      +
    • +
      + +
      +
      +
      +
      +
      +
      +
      + Incubate +

      New tools that fill a gap in the ecosystem but are not quite ready for wide-scale release and adoption.

      +
      +
      +
      +
      +
        + <%s! List.map render_tool incubate |> String.concat "" %> +
      +
      +
      +
      +
      +
      +
    • + +
    • +
      + +
      +
      +
      +
      +
      +
      +
      + Active +

      The work-horse tools that are used daily with strong backwards compatibility guarentees from the community.

      +
      +
      +
      +
      +
        + <%s! List.map render_tool active |> String.concat "" %> +
      +
      +
      +
      +
      +
      +
    • + +
    • +
      + +
      +
      +
      +
      +
      +
      +
      + Sustain +

      Tools that will not likely see any major feature added but can be used reliably even if not being actively developed.

      +
      +
      +
      +
      +
        + <%s! List.map render_tool sustain |> String.concat "" %> +
      +
      +
      +
      +
      +
      +
    • + +
    • +
      +
      +
      +
      +
      +
      +
      +
      + Deprecate +

      Tools that are gradually being phased out of use.

      +
      +
      +
      +
      +
        + <%s! List.map render_tool deprecate |> String.concat "" %> +
      +
      +
      +
      +
      +
      +
    • +
    +
    +
    +
    diff --git a/src/ood/tools.ml b/src/ood/tools.ml new file mode 100644 index 000000000..92ceb80cb --- /dev/null +++ b/src/ood/tools.ml @@ -0,0 +1,29 @@ +module Lifecycle = struct + type t = [ `Incubate | `Active | `Sustain | `Deprecate ] + + let to_string = function + | `Incubate -> "incubate" + | `Active -> "active" + | `Sustain -> "sustain" + | `Deprecate -> "deprecate" + + let of_string = function + | "incubate" -> Ok `Incubate + | "active" -> Ok `Active + | "sustain" -> Ok `Sustain + | "deprecate" -> Ok `Deprecate + | s -> Error (`Msg ("Unknown lifecycle type: " ^ s)) +end + +module Tool = struct + type t = { + name : string; + source : string; + license : string; + synopsis : string; + description : string; + lifecycle : Lifecycle.t; + } +end + +type t = { tools : Tool.t list }