From 6f390b887c89a4da11c2a61baba9608a65b30c94 Mon Sep 17 00:00:00 2001 From: Sabine Schmaltz Date: Fri, 23 Jun 2023 11:55:20 +0200 Subject: [PATCH] Add governance page #1239 (@sabine smaller box around dev-meeting on subteam ed627f6) --- data/governance.yml | 454 ++++++++++++++++++ src/global/url.ml | 4 +- src/ocamlorg_data/data.ml | 7 + src/ocamlorg_data/data.mli | 33 ++ src/ocamlorg_data/dune | 9 + src/ocamlorg_frontend/components/icons.eml | 10 + .../css/partials/governance.css | 15 + src/ocamlorg_frontend/css/styles.css | 1 + src/ocamlorg_frontend/dune | 13 +- src/ocamlorg_frontend/ocamlorg_frontend.ml | 2 + src/ocamlorg_frontend/pages/governance.eml | 93 ++++ .../pages/governance_team.eml | 144 ++++++ src/ocamlorg_web/lib/handler.ml | 12 +- src/ocamlorg_web/lib/redirection.ml | 1 - src/ocamlorg_web/lib/router.ml | 3 +- src/ocamlorg_web/lib/sitemap.ml | 1 + tool/ood-gen/bin/gen.ml | 1 + tool/ood-gen/lib/governance.ml | 113 +++++ 18 files changed, 911 insertions(+), 5 deletions(-) create mode 100644 data/governance.yml create mode 100644 src/ocamlorg_frontend/css/partials/governance.css create mode 100644 src/ocamlorg_frontend/pages/governance.eml create mode 100644 src/ocamlorg_frontend/pages/governance_team.eml create mode 100644 tool/ood-gen/lib/governance.ml diff --git a/data/governance.yml b/data/governance.yml new file mode 100644 index 0000000000..b498a8460e --- /dev/null +++ b/data/governance.yml @@ -0,0 +1,454 @@ +teams: +- id: compiler + name: Compiler + description: The OCaml Compiler team, responsible for the development and maintenance + of the language, the standard library and the compiler tools. + contacts: + - name: Mailing List + link: https://sympa.inria.fr/sympa/subscribe/caml-list + kind: email + - name: Discord + link: https://discord.com/channels/436568060288172042/904141760052228116 + kind: discord + - name: GitHub + link: https://github.com/ocaml/ocaml/issues + kind: github + members: + - name: Damien Doligez + github: damiendoligez + role: Lead Maintainer + - name: Xavier Leroy + github: xavierleroy + role: Owner + - name: Alain Frisch + github: alainfrisch + role: Maintainer + - name: "Arma\xEBl Gu\xE9neau" + github: Armael + role: Maintainer + - name: David Allsopp + github: dra27 + role: Maintainer + - name: Enguerrand + github: Engil + role: Maintainer + - name: Florian Angeletti + github: Octachron + role: Maintainer + - name: "Fr\xE9d\xE9ric Bour" + github: let-def + role: Maintainer + - name: Gabriel Scherer + github: gasche + role: Maintainer + - name: Jacques Garrigue + github: garrigue + role: Maintainer + - name: Jacques-Henri Jourdan + github: jhjourdan + role: Maintainer + - name: Jeremy Yallop + github: yallop + role: Maintainer + - name: KC Sivaramakrishnan + github: kayceesrk + role: Maintainer + - name: Leo White + github: lpw25 + role: Maintainer + - name: Luc Maranget + github: maranget + role: Maintainer + - name: Mark Shinwell + github: mshinwell + role: Maintainer + - name: "Nicol\xE1s Ojeda B\xE4r" + github: nojb + role: Maintainer + - name: Pierre Chambart + github: chambart + role: Maintainer + - name: Sadiq Jaffer + github: sadiqj + role: Maintainer + - name: Stephen Dolan + github: stedolan + role: Maintainer + - name: "S\xE9bastien Hinderer" + github: shindere + role: Maintainer + - name: Thomas Refis + github: trefis + role: Maintainer + - name: Vincent Laviron + github: lthls + role: Maintainer +- id: platform + name: Platform + description: The Platform team is responsible for the development and maintenance + of the OCaml Platform, the official OCaml developer toolchain. + contacts: + - name: Mailing List + link: https://lists.ocaml.org/listinfo/platform + kind: email + members: + - name: Anil Madhavapeddy + github: avsm + role: Owner + subteams: + - id: dune-dev + name: Dune + description: The Dune development team + contacts: + - name: GitHub + link: https://github.com/ocaml/dune + kind: github + members: + - name: Rudi Grinberg + github: rgrinberg + role: Maintainer + - name: Ali Caglayan + github: Alizter + role: Maintainer + - name: Nicolás Ojeda Bär + github: nojb + role: Maintainer + - name: Marek Kubica + github: Leonidas-from-XIV + role: Maintainer + - name: Etienne Millon + github: emillon + role: Maintainer + - name: Stephen Sherratt + github: gridbugs + role: Maintainer + - name: Antonio Nuno Monteiro + github: anmonteiro + role: Maintainer + - name: Javier Chávarri + github: jchavarri + role: Maintainer + - name: Andrey Mokhov + github: snowleopard + role: Maintainer + - name: Emilio Jesús Gallego Arias + github: ejgallego + role: Maintainer + - name: Françoit Botot + github: bobot + role: Maintainer + - id: opam-dev + name: Opam + description: The Opam development team + contacts: + - name: Mailing List + link: https://lists.ocaml.org/listinfo/opam-devel + kind: email + - name: GitHub + link: https://github.com/ocaml/opam + kind: github + members: + - name: Louis Gesbert + github: AltGr + role: Maintainer + - name: Raja Boujbel + github: rjbou + role: Maintainer + - name: David Allsopp + github: dra27 + role: Maintainer + - name: Kate Deplaix + github: kit-ty-kate + role: Maintainer + - id: ocaml-lsp-dev + name: Ocaml-lsp + description: The Ocaml-lsp development team + contacts: + - name: GitHub + link: https://github.com/ocaml/ocaml-lsp + kind: github + members: + - name: Rudi Grinberg + github: rgrinberg + role: Lead Maintainer + - name: Corentin Leruth + github: tatchi + role: Maintainer + - name: Ulysse + github: voodoos + role: Maintainer + - name: Rafał Gwoździński + github: 3Rafal + role: Maintainer + - id: merlin-dev + name: Merlin + description: The merlin development team + contacts: + - name: Mailing List + link: https://lists.ocaml.org/listinfo/merlin + kind: email + - name: GitHub + link: https://github.com/ocaml/merlin + kind: github + members: + - name: Ulysse Gérard + github: voodoos + role: Lead Maintainer + - name: Sonja Heinze + github: pitag-ha + role: Maintainer + - name: "Fr\xE9d\xE9ric Bour" + github: let-def + role: Maintainer + - name: Thomas Refis + github: trefis + role: Maintainer + - id: odoc-dev + name: Odoc + description: The odoc development team + contacts: + - name: GitHub + link: https://github.com/ocaml/odoc + kind: github + members: + - name: Jon Ludlam + github: jonludlam + role: Lead Maintainer + - name: "Daniel B\xFCnzli" + github: dbuenzli + role: Maintainer + - name: Leo White + github: lpw25 + role: Maintainer + - name: Thomas Refis + github: trefis + role: Maintainer + - name: Jules Aguillon + github: Julow + role: Maintainer + - name: Paul-Elliot Anglès D'Auriac + github: panglesd + role: Maintainer + - name: Emile Trotignon + github: EmileTrotignon + role: Maintainer + - name: Guillaume Petiot + github: gpetiot + role: Maintainer + - id: ppxlib-dev + name: Ppxlib + description: The ppxlib development team + contacts: + - name: GitHub + link: https://github.com/ocaml-ppx/ppxlib + kind: github + dev-meeting: + date: Every third Tuesday + time: 6:00 PM CET + link: https://meet.google.com/bwy-fyqo-dnf + invite: https://calendar.google.com/calendar/u/4?cid=Y19iMDA5ZDA4MDg0YzIwYWMzMDQ4NjJhN2FkZWJiYjdmOTU0NGIxYzEwMmU0MDMyMTAzMDFiY2ZhYjcwMDBmMjNlQGdyb3VwLmNhbGVuZGFyLmdvb2dsZS5jb20 + notes: https://github.com/ocaml-ppx/ppxlib/wiki + members: + - name: Sonja Heinze + github: pitag-ha + role: Lead Maintainer + - name: Carl Eastlund + github: ceastlund + role: Maintainer + - name: "Paul-Elliot Angl\xE8s d'Auriac" + github: panglesd + role: Maintainer + - id: utop-dev + name: Utop + description: The Utop development team + contacts: + - name: GitHub + link: https://github.com/ocaml-community/utop + kind: github + members: + - name: Etienne Millon + github: emillon + role: Lead Maintainer + - name: Rudi Grinberg + github: rgrinberg + role: Maintainer + - id: opam-publish-dev + name: Opam-publish + description: The Opam-publish development team + contacts: + - name: GitHub + link: https://github.com/ocaml-opam/opam-publish + kind: github + members: + - name: Louis Gesbert + github: AltGr + role: Maintainer + - name: Raja Boujbel + github: rjbou + role: Maintainer + - name: Kate + github: kit-ty-kate + role: Maintainer + - id: ocamlformat-dev + name: Ocamlformat + description: The Ocamlformat development team + contacts: + - name: Mailing List + link: https://lists.ocaml.org/listinfo/listinfo/ocamlformat-dev + kind: email + - name: GitHub + link: https://github.com/ocaml-ppx/ocamlformat + kind: github + members: + - name: Guillaume Petiot + github: gpetiot + role: Lead Maintainer + - name: Jules Aguillon + github: Julow + role: Maintainer + - name: Emile Trotignon + github: EmileTrotignon + role: Maintainer + - id: dune-release-dev + name: Dune-release + description: The Dune-release development team + contacts: + - name: GitHub + link: https://github.com/tarides/dune-release + kind: github + members: + - name: Etienne Millon + github: emillon + role: Maintainer + - name: Marek Kubica + github: Leonidas-from-XIV + role: Maintainer + - id: mdx-dev + name: Mdx + description: The Mdx development team + contacts: + - name: GitHub + link: https://github.com/realworldocaml/mdx + kind: github + members: + - name: Marek Kubica + github: Leonidas-from-XIV + role: Lead Maintainer + - id: ocp-indent-dev + name: Ocp-indent + description: The Ocp-indent development team + contacts: + - name: GitHub + link: https://github.com/OCamlPro/ocp-indent + kind: github + members: + - name: Louis Gesbert + github: AltGr + role: Lead Maintainer + - id: ocamlfind-dev + name: Ocamlfind + description: The Ocamlfind development team + contacts: + - name: GitHub + link: https://github.com/ocaml/ocamlfind + kind: github + members: + - name: Gerd Stolpmann + github: gerdstolpmann + role: Lead Maintainer + - name: David Allsopp + github: dra27 + role: Maintainer + - id: omp-dev + name: Omp + description: The Omp development team + contacts: + - name: GitHub + link: https://github.com/ocaml-ppx/ocaml-migrate-parsetree + kind: github + members: + - name: Sonja Heinze + github: pitag-ha + role: Lead Maintainer +- id: packaging + name: Packaging + description: The Packaging team is responsible to ensure the quality of the OCaml + packages ecosystem, and in particular, to review submitions to the Opam repository. + contacts: + - name: GitHub + link: https://github.com/ocaml/opam-repository + kind: github + members: + - name: Anil Madhavapeddy + github: avsm + role: Lead Maintainer + - name: Kate Deplaix + github: kit-ty-kate + role: Maintainer + - name: Marcello Seri + github: mseri + role: Maintainer +- id: infrastructure + name: Infrastructure + description: The infrastructure team is responsible to maintain and evolve the infrastructure + powering the official OCaml projects, including the servers for OCaml.org and + the opam-repository CI. + contacts: + - name: Mailing List + link: https://lists.ocaml.org/listinfo/listinfo/infrastructure + kind: email + - name: GitHub + link: https://github.com/ocaml/infrastructure/issues + kind: github + members: + - name: Anil Madhavapeddy + github: avsm + role: Owner + - name: Tim McGilchrist + github: tmcgilchrist + role: Lead Maintainer + - name: Kate + github: kit-ty-kate + role: Maintainer + - name: Mark Elvers + github: mtelvers + role: Maintainer +- id: web + name: Web + description: The Web team is responsible for the development and maintenance of + the official OCaml websites, in particular OCaml.org and its subdomains. + contacts: + - name: GitHub + link: https://github.com/ocaml/ocaml.org + kind: github + members: + - name: Anil Madhavapeddy + github: avsm + role: Owner + - name: Thibaut Mattio + github: tmattio + role: Lead Maintainer + - name: Sabine Schmaltz + github: sabine + role: Maintainer + - name: Cuihtlauac Alvarado + github: cuihtlauac + role: Maintainer +working-groups: +- id: wg-eio + name: Eio Working Group + description: Work on tools and libraries to do multicore programming with OCaml. + contacts: + - name: Matrix + link: https://matrix.to/#/#eio:roscidus.com + kind: chat + dev-meeting: + date: Bi-weekly on Mondays + time: 10:00 AM BST + link: http://meet.google.com/byo-dfiz-dou + invite: https://calendar.google.com/calendar/u/4?cid=Y19iMDA5ZDA4MDg0YzIwYWMzMDQ4NjJhN2FkZWJiYjdmOTU0NGIxYzEwMmU0MDMyMTAzMDFiY2ZhYjcwMDBmMjNlQGdyb3VwLmNhbGVuZGFyLmdvb2dsZS5jb20 + notes: https://docs.google.com/document/d/1ZBfbjAkvEkv9ldumpZV5VXrEc_HpPeYjHPW_TiwJe4Q/ + members: + - name: Sudha Parimala + github: Sudha247 + role: Organiser diff --git a/src/global/url.ml b/src/global/url.ml index 462869a5c3..dda4a03b13 100644 --- a/src/global/url.ml +++ b/src/global/url.ml @@ -58,9 +58,11 @@ let blog_post v = "/blog/" ^ v let news = "/news" let news_post v = "/news/" ^ v let jobs = "/jobs" +let governance = "/governance" +let governance_team id = "/governance/" ^ id let carbon_footprint = "/policies/carbon-footprint" let privacy_policy = "/policies/privacy-policy" -let governance = "/policies/governance" +let governance_policy = "/policies/governance" let code_of_conduct = "/policies/code-of-conduct" let playground = "/play" let papers = "/papers" diff --git a/src/ocamlorg_data/data.ml b/src/ocamlorg_data/data.ml index 5bf352baef..d29e36c1ff 100644 --- a/src/ocamlorg_data/data.ml +++ b/src/ocamlorg_data/data.ml @@ -165,3 +165,10 @@ module Code_example = struct let get title = List.find (fun x -> String.equal x.title title) all end + +module Governance = struct + include Governance + + let get_by_id id = + List.find_opt (fun x -> String.equal id x.id) (teams @ working_groups) +end diff --git a/src/ocamlorg_data/data.mli b/src/ocamlorg_data/data.mli index a194ce6e61..a03e9ca7b6 100644 --- a/src/ocamlorg_data/data.mli +++ b/src/ocamlorg_data/data.mli @@ -400,3 +400,36 @@ module Code_example : sig val get : string -> t end + +module Governance : sig + module Member : sig + type t = { name : string; github : string; role : string } + + val compare : t -> t -> int + end + + type contact_kind = GitHub | Email | Discord | Chat + type contact = { name : string; link : string; kind : contact_kind } + + type dev_meeting = { + date : string; + time : string; + link : string; + invite : string; + notes : string; + } + + type team = { + id : string; + name : string; + description : string; + contacts : contact list; + dev_meeting : dev_meeting option; + members : Member.t list; + subteams : team list; + } + + val teams : team list + val working_groups : team list + val get_by_id : string -> team option +end diff --git a/src/ocamlorg_data/dune b/src/ocamlorg_data/dune index 9d6742dc1d..ea3382e257 100644 --- a/src/ocamlorg_data/dune +++ b/src/ocamlorg_data/dune @@ -17,6 +17,15 @@ (run %{dep:../../tool/ood-gen/bin/gen.exe} book)))) (rule + (deps ../../tool/ood-gen/bin/gen.exe) + (target governance.ml) + (action + (with-stdout-to + %{target} + (run %{dep:../../tool/ood-gen/bin/gen.exe} governance)))) + +(rule + (deps ../../tool/ood-gen/bin/gen.exe) (target changelog.ml) (action (with-stdout-to diff --git a/src/ocamlorg_frontend/components/icons.eml b/src/ocamlorg_frontend/components/icons.eml index af539a98a5..f8059def94 100644 --- a/src/ocamlorg_frontend/components/icons.eml +++ b/src/ocamlorg_frontend/components/icons.eml @@ -41,6 +41,11 @@ let changelog class_ = +let chat class_ = + + let chevron_down class_ = +let email class_ = + + let error class_ =
+
+ <%s team.name %> + + + +
+
<%s team.description %>
+
<%i count_members team %> <%s member_label %>
+ + Details + + + + +
+ +let render ~teams ~working_groups = +Layout.render +~title:"Governance" +~description:"OCaml is a mature, statically-typed, functional programming language. Learn more about its rich history +and what makes it unique." @@ +
+
+
+
+
+

Governance

+
The projects running under OCaml and the awesome people + behind it +
+ +
+
+
+
+
+ +
+
+
+

Teams

+
+ See who the maintainers of the various OCaml projects are. We present a comprehensive list structured by project / purpose. +
+
+ <% teams |> List.iter (fun (team : Data.Governance.team) -> %> + <%s! render_team_card team "maintainers" "btn-tertiary" %> + <% );%> +
+
+
+
+ + + + + + + + + + + + + + +
+
+
+

Working groups

+
+ Working groups gather around certain topics or a shared purpose. Participation is welcome and encouraged.
+
+ <% working_groups |> List.iter (fun (wg : Data.Governance.team) -> %> + <%s! render_team_card wg "organiser(s)" "btn-secondary" %> + <% ); %> +
+
+
+
\ No newline at end of file diff --git a/src/ocamlorg_frontend/pages/governance_team.eml b/src/ocamlorg_frontend/pages/governance_team.eml new file mode 100644 index 0000000000..4151ba107a --- /dev/null +++ b/src/ocamlorg_frontend/pages/governance_team.eml @@ -0,0 +1,144 @@ +let contact_icon (kind : Data.Governance.contact_kind) = match kind with + | GitHub -> Icons.github + | Email -> Icons.email + | Discord -> Icons.discord + | Chat -> Icons.chat + +let render_team_member (member : Data.Governance.Member.t) = +
+ +
+
<%s member.name %>
+
<%s member.role %>
+
+ <%s! Icons.github "h-6 w-6" %> + <%s member.github %> +
+
+
+ +let render_dev_meeting (dev_meeting : Data.Governance.dev_meeting) _class = + + +let render (t : Data.Governance.team) = +Layout.render +~title:(Printf.sprintf "%s · OCaml Governance" t.name) +~description:t.description @@ +
+
+
+
+
+
+ + + + + Back to Governance +
+

<%s t.name %> Governance

+
+ <%s t.description%> +
+
+ <% t.contacts |> List.iter (fun (contact : Data.Governance.contact) -> %> + + <%s! contact_icon contact.kind "w-6 h-6" %> + <%s contact.name %> + + <% ); %> +
+
+
+
+
+
+
+
+
+ <% (match t.dev_meeting with | None -> () | Some dev_meeting -> %> +

Dev Meeting

+ <%s! render_dev_meeting dev_meeting "text-white mb-6" %> + <% ); %> + +

People

+
+ <%s! t.members |> List.map (fun (member : Data.Governance.Member.t) -> render_team_member member ) |> String.concat "\n" %> +
+ + <% (match List.length t.subteams with | 0 -> () | _ -> %> +

Teams

+ <% ); %> +
+ <% t.subteams |> List.iter (fun (team : Data.Governance.team) -> %> +
+

<%s team.name %>

+ <% (if List.length t.contacts > 0 then %> +
+ <% team.contacts |> List.iter (fun (contact : Data.Governance.contact) -> %> + + <%s! contact_icon contact.kind "w-6 h-6" %> + <%s contact.name %> + + <% ); %> +
+ <% ); %> + <% (match team.dev_meeting with | None -> () | Some dev_meeting -> %> +
+

Dev Meeting

+ <%s! render_dev_meeting dev_meeting "" %> +
+ <% ); %> +
+ <%s! team.members |> List.map (fun (member : Data.Governance.Member.t) -> render_team_member member ) |> String.concat "\n" %> +
+
+ <% ); %> +
+
+
+
+ + + + + + + + + + + + + + + + + + + + diff --git a/src/ocamlorg_web/lib/handler.ml b/src/ocamlorg_web/lib/handler.ml index fa15c23a84..8acca6d6e1 100644 --- a/src/ocamlorg_web/lib/handler.ml +++ b/src/ocamlorg_web/lib/handler.ml @@ -230,7 +230,7 @@ let page canonical (_req : Dream.request) = let carbon_footprint = page Url.carbon_footprint let privacy_policy = page Url.privacy_policy -let governance = page Url.governance +let governance_policy = page Url.governance_policy let code_of_conduct = page Url.code_of_conduct let playground _req = @@ -238,6 +238,16 @@ let playground _req = let default_code = default.body in Dream.html (Ocamlorg_frontend.playground ~default_code) +let governance _req = + Dream.html + (Ocamlorg_frontend.governance ~teams:Data.Governance.teams + ~working_groups:Data.Governance.working_groups) + +let governance_team req = + let id = Dream.param req "id" in + let? team = Data.Governance.get_by_id id in + Dream.html (Ocamlorg_frontend.governance_team team) + let papers req = let search_paper pattern t = let open Data.Paper in diff --git a/src/ocamlorg_web/lib/redirection.ml b/src/ocamlorg_web/lib/redirection.ml index 42c9f6d3fd..71f9aadb63 100644 --- a/src/ocamlorg_web/lib/redirection.ml +++ b/src/ocamlorg_web/lib/redirection.ml @@ -702,7 +702,6 @@ let t = make ~permanent:true [ ("/carbon-footprint", "/policies/carbon-footprint") ]; make ~permanent:true [ ("/privacy-policy", "/policies/privacy-policy") ]; - make ~permanent:true [ ("/governance", "/policies/governance") ]; make ~permanent:true [ ("/code-of-conduct", "/policies/code-of-conduct") ]; make ~permanent:true [ ("/opportunities", "/jobs") ]; make ~permanent:false [ (Url.workshops, Url.community ^ "#workshops") ]; diff --git a/src/ocamlorg_web/lib/router.ml b/src/ocamlorg_web/lib/router.ml index c719d3bae8..8bcf1d16c6 100644 --- a/src/ocamlorg_web/lib/router.ml +++ b/src/ocamlorg_web/lib/router.ml @@ -46,7 +46,8 @@ let page_routes = Dream.get Url.carbon_footprint Handler.carbon_footprint; Dream.get Url.privacy_policy Handler.privacy_policy; Dream.get Url.governance Handler.governance; - Dream.get Url.code_of_conduct Handler.code_of_conduct; + Dream.get (Url.governance_team ":id") Handler.governance_team; + Dream.get Url.governance_policy Handler.governance_policy; Dream.get Url.papers Handler.papers; Dream.get Url.best_practices Handler.best_practices; Dream.get Url.problems Handler.problems; diff --git a/src/ocamlorg_web/lib/sitemap.ml b/src/ocamlorg_web/lib/sitemap.ml index 4fbf2bec43..ebaf2dfa17 100644 --- a/src/ocamlorg_web/lib/sitemap.ml +++ b/src/ocamlorg_web/lib/sitemap.ml @@ -19,6 +19,7 @@ let urls = Url.jobs; Url.carbon_footprint; Url.privacy_policy; + Url.governance_policy; Url.governance; Url.code_of_conduct; Url.playground; diff --git a/tool/ood-gen/bin/gen.ml b/tool/ood-gen/bin/gen.ml index 685269f4c5..9180d70898 100644 --- a/tool/ood-gen/bin/gen.ml +++ b/tool/ood-gen/bin/gen.ml @@ -4,6 +4,7 @@ let term_templates = [ ("academic_institution", Ood_gen.Academic_institution.template); ("book", Ood_gen.Book.template); + ("governance", Ood_gen.Governance.template); ("job", Ood_gen.Job.template); ("meetup", Ood_gen.Meetup.template); ("news", Ood_gen.News.template); diff --git a/tool/ood-gen/lib/governance.ml b/tool/ood-gen/lib/governance.ml new file mode 100644 index 0000000000..182188a307 --- /dev/null +++ b/tool/ood-gen/lib/governance.ml @@ -0,0 +1,113 @@ +open Ocamlorg.Import + +type contact_kind = GitHub | Email | Discord | Chat +[@@deriving show { with_path = false }] + +let contact_kind_of_yaml = function + | `String "github" -> Ok GitHub + | `String "email" -> Ok Email + | `String "discord" -> Ok Discord + | `String "chat" -> Ok Chat + | x -> ( + match Yaml.to_string x with + | Ok str -> + Error + (`Msg + ("\"" ^ str + ^ "\" is not a valid contact_kind! valid options are: github, \ + email, discord, chat")) + | Error _ -> Error (`Msg "Invalid Yaml value")) + +let contact_kind_to_yaml = function + | GitHub -> `String "github" + | Email -> `String "email" + | Discord -> `String "discord" + | Chat -> `String "chat" + +type member = { name : string; github : string; role : string } +[@@deriving yaml, show { with_path = false }] + +type contact = { name : string; link : string; kind : contact_kind } +[@@deriving yaml, show { with_path = false }] + +type dev_meeting = { + date : string; + time : string; + link : string; + invite : string; + notes : string; +} +[@@deriving yaml, show { with_path = false }] + +type team = { + id : string; + name : string; + description : string; + contacts : contact list; + dev_meeting : dev_meeting option; [@default None] [@key "dev-meeting"] + members : member list; [@default []] + subteams : team list; [@default []] +} +[@@deriving yaml, show { with_path = false }] + +type metadata = { + teams : team list; + working_groups : team list; [@key "working-groups"] +} +[@@deriving yaml] + +type t = { teams : team list; working_groups : team list } +[@@deriving stable_record ~version:metadata, show { with_path = false }] + +let decode s = Result.map of_metadata (metadata_of_yaml s) + +let all () = + let file = "governance.yml" in + let result = + let ( let* ) = Result.bind in + let* yaml = Utils.yaml_file file in + decode yaml + in + result + |> Result.map_error (function `Msg err -> `Msg (file ^ ": " ^ err)) + |> Result.get_ok ~error:(fun (`Msg msg) -> Exn.Decode_error msg) + +let template () = + let t = all () in + Format.asprintf + {| +module Member = struct + type t = { name : string; github : string; role : string } + let compare a b = String.compare a.github b.github +end + +type contact_kind = GitHub | Email | Discord | Chat + +type contact = { name : string; link : string; kind : contact_kind } + +type dev_meeting = { + date : string; + time : string; + link : string; + invite : string; + notes : string; +} + +type team = { + id : string; + name : string; + description : string; + contacts : contact list; + dev_meeting : dev_meeting option; + members : Member.t list; + subteams : team list; +} + +let teams = %a + +let working_groups = %a +|} + (Fmt.brackets (Fmt.list pp_team ~sep:Fmt.semi)) + t.teams + (Fmt.brackets (Fmt.list pp_team ~sep:Fmt.semi)) + t.working_groups