Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #require "opam-state"
- #require "fpath"
- module Conversions = struct
- let version_of_pkg pkg =
- OpamPackage.version pkg |> OpamPackage.Version.to_string
- end
- type t = { name : string; ver : string }
- let binary_name ~ocaml ~name ~ver ~pure_binary =
- let name = if pure_binary then name else name ^ "+bin+platform" in
- let ocaml_version = Conversions.version_of_pkg ocaml in
- { name; ver = ver ^ "-ocaml" ^ ocaml_version }
- type tool = { name : string; pure_binary : bool; version : string option }
- module Syntax = struct
- let ( let+ ) x f = Result.map f x
- let ( let* ) x f = Result.bind x f
- let ( >>| ) x f = Result.map f x
- let ( >>= ) x f = Result.bind x f
- end
- let errorf fmt = Format.kasprintf (fun msg -> Error (`Msg msg)) fmt
- open Syntax
- let platform () =
- [
- { name = "dune"; pure_binary = true; version = None };
- { name = "dune-release"; pure_binary = false; version = None };
- { name = "merlin"; pure_binary = false; version = None };
- { name = "ocaml-lsp-server"; pure_binary = false; version = None };
- { name = "odoc"; pure_binary = false; version = None };
- { name = "ocamlformat"; pure_binary = false; version = None };
- ]
- let installed_versions pkg_names (sel : OpamTypes.switch_selections) =
- let installed_pkgs = sel.sel_installed in
- List.map
- (fun name ->
- let version =
- OpamPackage.package_of_name_opt installed_pkgs
- @@ OpamPackage.Name.of_string name
- in
- (name, version))
- pkg_names
- let get_pkg_universe (switch_state : 'lock OpamStateTypes.switch_state) =
- switch_state.available_packages
- let get_metadata_universe (switch_state : 'lock OpamStateTypes.switch_state) =
- switch_state.opams
- let get_switch = function
- | None -> OpamStateConfig.get_switch ()
- | Some dir ->
- OpamSwitch.of_dirname (Fpath.to_string dir |> OpamFilename.Dir.of_string)
- let with_switch_state ?dir_name f =
- let switch = get_switch dir_name in
- OpamGlobalState.with_ `Lock_read (fun global_state ->
- OpamSwitchState.with_ `Lock_read global_state ~switch (fun switch_state ->
- f switch_state))
- let with_switch_state_sel ?dir_name f =
- let switch = get_switch dir_name in
- OpamGlobalState.with_ `Lock_read (fun global_state ->
- let sel =
- OpamSwitchState.load_selections ~lock_kind:`Lock_read global_state
- switch
- in
- f sel)
- let with_virtual_state f =
- OpamGlobalState.with_ `Lock_read (fun global_state ->
- OpamRepositoryState.with_ `Lock_read global_state (fun repo_state ->
- let virtual_state =
- OpamSwitchState.load_virtual global_state repo_state
- in
- f virtual_state))
- let init () =
- OpamFormatConfig.init ();
- let root = OpamStateConfig.opamroot () in
- OpamStateConfig.load_defaults root |> ignore;
- OpamStateConfig.init ~root_dir:root ()
- let () = init ()
- let latest_version ~metadata_universe ~pkg_universe ~ocaml package =
- let package = OpamPackage.Name.of_string package in
- let compatible_ones =
- OpamPackage.Set.filter
- (fun pkg ->
- OpamPackage.Name.equal (OpamPackage.name pkg) package
- &&
- let pkg_opam_file = OpamPackage.Map.find pkg metadata_universe in
- let dependencies = OpamFile.OPAM.depends pkg_opam_file in
- let env _ = None in
- OpamFormula.verifies
- (OpamPackageVar.filter_depends_formula ~env dependencies)
- ocaml)
- pkg_universe
- in
- try Some (OpamPackage.max_version compatible_ones package)
- with Not_found -> None
- let best_version ~metadata_universe ~pkg_universe ~ocaml tool =
- (match tool.version with
- | Some ver -> Ok ver
- | None -> (
- match
- latest_version ~metadata_universe
- ~pkg_universe:(Lazy.force pkg_universe) ~ocaml tool.name
- with
- | Some ver -> Ok (Conversions.version_of_pkg ver)
- | None ->
- errorf "Something went wrong trying to find the best version for %s"
- tool.name))
- >>| fun ver ->
- binary_name ~ocaml ~name:tool.name ~ver ~pure_binary:tool.pure_binary
- module Syntax = struct
- let ( let+ ) x f = Result.map f x
- let ( let* ) x f = Result.bind x f
- let ( >>| ) x f = Result.map f x
- let ( >>= ) x f = Result.bind x f
- end
- open Syntax
- let f () =
- let tools = platform () in
- let tools_names = List.map (fun tool -> tool.name) tools in
- let installed =
- with_switch_state_sel (installed_versions ("ocaml" :: tools_names))
- in
- let ocaml =
- match List.assoc_opt "ocaml" installed with
- | Some (Some s) -> s
- | _ -> failwith "Cannot install tools: No switch with compiler is selected."
- in
- let pkg_universe, metadata_universe =
- with_virtual_state (fun state ->
- (get_pkg_universe state, get_metadata_universe state))
- in
- List.fold_left
- (fun to_build tool ->
- let bname = best_version ~metadata_universe ~pkg_universe ~ocaml tool in
- bname :: to_build)
- [] tools
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement