Advertisement
panglesd

after use of opam library

Jun 28th, 2022
767
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 4.93 KB | None | 0 0
  1. #require "opam-state"
  2.  
  3. #require "fpath"
  4.  
  5. module Conversions = struct
  6.   let version_of_pkg pkg =
  7.     OpamPackage.version pkg |> OpamPackage.Version.to_string
  8. end
  9.  
  10. type t = { name : string; ver : string }
  11.  
  12. let binary_name ~ocaml ~name ~ver ~pure_binary =
  13.   let name = if pure_binary then name else name ^ "+bin+platform" in
  14.   let ocaml_version = Conversions.version_of_pkg ocaml in
  15.   { name; ver = ver ^ "-ocaml" ^ ocaml_version }
  16.  
  17. type tool = { name : string; pure_binary : bool; version : string option }
  18.  
  19. module Syntax = struct
  20.   let ( let+ ) x f = Result.map f x
  21.   let ( let* ) x f = Result.bind x f
  22.   let ( >>| ) x f = Result.map f x
  23.   let ( >>= ) x f = Result.bind x f
  24. end
  25.  
  26. let errorf fmt = Format.kasprintf (fun msg -> Error (`Msg msg)) fmt
  27.  
  28. open Syntax
  29.  
  30. let platform () =
  31.   [
  32.     { name = "dune"; pure_binary = true; version = None };
  33.     { name = "dune-release"; pure_binary = false; version = None };
  34.     { name = "merlin"; pure_binary = false; version = None };
  35.     { name = "ocaml-lsp-server"; pure_binary = false; version = None };
  36.     { name = "odoc"; pure_binary = false; version = None };
  37.     { name = "ocamlformat"; pure_binary = false; version = None };
  38.   ]
  39.  
  40. let installed_versions pkg_names (sel : OpamTypes.switch_selections) =
  41.   let installed_pkgs = sel.sel_installed in
  42.   List.map
  43.     (fun name ->
  44.       let version =
  45.         OpamPackage.package_of_name_opt installed_pkgs
  46.         @@ OpamPackage.Name.of_string name
  47.       in
  48.       (name, version))
  49.     pkg_names
  50.  
  51. let get_pkg_universe (switch_state : 'lock OpamStateTypes.switch_state) =
  52.   switch_state.available_packages
  53.  
  54. let get_metadata_universe (switch_state : 'lock OpamStateTypes.switch_state) =
  55.   switch_state.opams
  56.  
  57. let get_switch = function
  58.   | None -> OpamStateConfig.get_switch ()
  59.   | Some dir ->
  60.       OpamSwitch.of_dirname (Fpath.to_string dir |> OpamFilename.Dir.of_string)
  61.  
  62. let with_switch_state ?dir_name f =
  63.   let switch = get_switch dir_name in
  64.   OpamGlobalState.with_ `Lock_read (fun global_state ->
  65.       OpamSwitchState.with_ `Lock_read global_state ~switch (fun switch_state ->
  66.           f switch_state))
  67.  
  68. let with_switch_state_sel ?dir_name f =
  69.   let switch = get_switch dir_name in
  70.   OpamGlobalState.with_ `Lock_read (fun global_state ->
  71.       let sel =
  72.         OpamSwitchState.load_selections ~lock_kind:`Lock_read global_state
  73.           switch
  74.       in
  75.       f sel)
  76.  
  77. let with_virtual_state f =
  78.   OpamGlobalState.with_ `Lock_read (fun global_state ->
  79.       OpamRepositoryState.with_ `Lock_read global_state (fun repo_state ->
  80.           let virtual_state =
  81.             OpamSwitchState.load_virtual global_state repo_state
  82.           in
  83.           f virtual_state))
  84.  
  85. let init () =
  86.   OpamFormatConfig.init ();
  87.   let root = OpamStateConfig.opamroot () in
  88.   OpamStateConfig.load_defaults root |> ignore;
  89.   OpamStateConfig.init ~root_dir:root ()
  90.  
  91. let () = init ()
  92.  
  93. let latest_version ~metadata_universe ~pkg_universe ~ocaml package =
  94.   let package = OpamPackage.Name.of_string package in
  95.   let compatible_ones =
  96.     OpamPackage.Set.filter
  97.       (fun pkg ->
  98.         OpamPackage.Name.equal (OpamPackage.name pkg) package
  99.         &&
  100.         let pkg_opam_file = OpamPackage.Map.find pkg metadata_universe in
  101.         let dependencies = OpamFile.OPAM.depends pkg_opam_file in
  102.         let env _ = None in
  103.         OpamFormula.verifies
  104.           (OpamPackageVar.filter_depends_formula ~env dependencies)
  105.           ocaml)
  106.       pkg_universe
  107.   in
  108.   try Some (OpamPackage.max_version compatible_ones package)
  109.   with Not_found -> None
  110.  
  111. let best_version ~metadata_universe ~pkg_universe ~ocaml tool =
  112.   (match tool.version with
  113.   | Some ver -> Ok ver
  114.   | None -> (
  115.       match
  116.         latest_version ~metadata_universe
  117.           ~pkg_universe:(Lazy.force pkg_universe) ~ocaml tool.name
  118.       with
  119.       | Some ver -> Ok (Conversions.version_of_pkg ver)
  120.       | None ->
  121.           errorf "Something went wrong trying to find the best version for %s"
  122.             tool.name))
  123.   >>| fun ver ->
  124.   binary_name ~ocaml ~name:tool.name ~ver ~pure_binary:tool.pure_binary
  125.  
  126. module Syntax = struct
  127.   let ( let+ ) x f = Result.map f x
  128.   let ( let* ) x f = Result.bind x f
  129.   let ( >>| ) x f = Result.map f x
  130.   let ( >>= ) x f = Result.bind x f
  131. end
  132.  
  133. open Syntax
  134.  
  135. let f () =
  136.   let tools = platform () in
  137.   let tools_names = List.map (fun tool -> tool.name) tools in
  138.   let installed =
  139.     with_switch_state_sel (installed_versions ("ocaml" :: tools_names))
  140.   in
  141.   let ocaml =
  142.     match List.assoc_opt "ocaml" installed with
  143.     | Some (Some s) -> s
  144.     | _ -> failwith "Cannot install tools: No switch with compiler is selected."
  145.   in
  146.   let pkg_universe, metadata_universe =
  147.     with_virtual_state (fun state ->
  148.         (get_pkg_universe state, get_metadata_universe state))
  149.   in
  150.  
  151.   List.fold_left
  152.     (fun to_build tool ->
  153.       let bname = best_version ~metadata_universe ~pkg_universe ~ocaml tool in
  154.       bname :: to_build)
  155.     [] tools
  156.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement