1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
|
open Import
module Lock_dir = Dune_pkg.Lock_dir
module Solver_env = Dune_pkg.Solver_env
module Package_variable_name = Dune_lang.Package_variable_name
module Variable_value = Dune_pkg.Variable_value
let solver_env
~solver_env_from_current_system
~solver_env_from_context
~unset_solver_vars_from_context
=
let solver_env =
[ solver_env_from_current_system; solver_env_from_context ]
|> List.filter_opt
|> List.fold_left ~init:Solver_env.with_defaults ~f:Solver_env.extend
in
match unset_solver_vars_from_context with
| None -> solver_env
| Some unset_solver_vars -> Solver_env.unset_multi solver_env unset_solver_vars
;;
let poll_solver_env_from_current_system () =
Dune_pkg.Sys_poll.make ~path:(Env_path.path Stdune.Env.initial)
|> Dune_pkg.Sys_poll.solver_env_from_current_system
;;
let get_lock_dir_from_context ~lock_dir_path =
Memo.run
@@
let open Memo.O in
let+ workspace = Workspace.workspace () in
Workspace.find_lock_dir workspace lock_dir_path
;;
let get_solver_env_from_context ~lock_dir_path =
let open Fiber.O in
let+ lock_dir = get_lock_dir_from_context ~lock_dir_path in
Option.bind lock_dir ~f:(fun lock_dir -> lock_dir.solver_env)
;;
let get_unset_solver_vars_from_context ~lock_dir_path =
let open Fiber.O in
let+ lock_dir = get_lock_dir_from_context ~lock_dir_path in
Option.bind lock_dir ~f:(fun lock_dir -> lock_dir.unset_solver_vars)
;;
let solver_env_from_system_and_context ~lock_dir_path =
let open Fiber.O in
let+ solver_env_from_current_system =
poll_solver_env_from_current_system () >>| Option.some
and+ solver_env_from_context = get_solver_env_from_context ~lock_dir_path
and+ unset_solver_vars_from_context =
get_unset_solver_vars_from_context ~lock_dir_path
in
solver_env
~solver_env_from_current_system
~solver_env_from_context
~unset_solver_vars_from_context
;;
module Version_preference = struct
include Dune_pkg.Version_preference
let term =
let all_strings = List.map all_by_string ~f:fst in
let doc =
sprintf
"Whether to prefer the newest compatible version of a package or the oldest \
compatible version of packages while solving dependencies. This overrides any \
setting in the current workspace. The default is %s."
(to_string default)
in
let docv = String.concat ~sep:"|" all_strings |> sprintf "(%s)" in
Arg.(
value
& opt (some (enum all_by_string)) None
& info [ "version-preference" ] ~doc:(Some doc) ~docv)
;;
let choose ~from_arg ~from_context =
match from_arg, from_context with
| Some from_arg, _ -> from_arg
| None, Some from_context -> from_context
| None, None -> default
;;
end
let repositories_of_workspace (workspace : Workspace.t) =
List.map workspace.repos ~f:(fun repo ->
Dune_pkg.Pkg_workspace.Repository.name repo, repo)
|> Dune_pkg.Pkg_workspace.Repository.Name.Map.of_list_exn
;;
let constraints_of_workspace (workspace : Workspace.t) ~lock_dir_path =
match Workspace.find_lock_dir workspace lock_dir_path with
| None -> []
| Some lock_dir -> lock_dir.constraints
;;
let depopts_of_workspace (workspace : Workspace.t) ~lock_dir_path =
match Workspace.find_lock_dir workspace lock_dir_path with
| None -> []
| Some lock_dir -> lock_dir.depopts |> List.map ~f:snd
;;
let repositories_of_lock_dir workspace ~lock_dir_path =
match Workspace.find_lock_dir workspace lock_dir_path with
| Some lock_dir -> lock_dir.repositories
| None ->
List.map workspace.repos ~f:(fun repo ->
let name = Dune_pkg.Pkg_workspace.Repository.name repo in
let loc = Loc.none in
loc, name)
;;
let unset_solver_vars_of_workspace workspace ~lock_dir_path =
let open Option.O in
let* lock_dir = Workspace.find_lock_dir workspace lock_dir_path in
lock_dir.unset_solver_vars
;;
let find_local_packages =
let open Memo.O in
Dune_rules.Dune_load.packages ()
>>| Package.Name.Map.map ~f:Dune_pkg.Local_package.of_package
;;
let pp_package { Lock_dir.Pkg.info = { Lock_dir.Pkg_info.name; version; avoid; _ }; _ } =
let warn =
if avoid
then Pp.tag User_message.Style.Warning (Pp.text " (this version should be avoided)")
else Pp.nop
in
let open Pp.O in
Pp.verbatim
(Package_name.to_string name ^ "." ^ Dune_pkg.Package_version.to_string version)
++ warn
;;
let pp_packages packages = Pp.enumerate packages ~f:pp_package
module Lock_dirs_arg = struct
type t =
| All
| Selected of Path.Source.t list
let all = All
let term =
Common.one_of
(let+ arg =
Arg.(
value
& pos_all string []
& info
[]
~docv:"LOCKDIRS"
~doc:
(Some
"Lock directories to check for outdated packages. Defaults to \
dune.lock."))
in
Selected (List.map arg ~f:Path.Source.of_string))
(let+ _all =
Arg.(
value
& flag
& info
[ "all" ]
~doc:
(Some
"Check all lock directories in the workspace for outdated packages."))
in
All)
;;
let lock_dirs_of_workspace t (workspace : Workspace.t) =
let module Set = Path.Source.Set in
let default_path = Dune_rules.Lock_dir.default_source_path in
let workspace_lock_dirs =
default_path
:: List.map workspace.lock_dirs ~f:(fun (lock_dir : Workspace.Lock_dir.t) ->
lock_dir.path)
|> Set.of_list
|> Set.to_list
in
match t with
| All -> workspace_lock_dirs
| Selected [] -> [ default_path ]
| Selected chosen_lock_dirs ->
let workspace_lock_dirs_set = Set.of_list workspace_lock_dirs in
let chosen_lock_dirs_set = Set.of_list chosen_lock_dirs in
if Set.is_subset chosen_lock_dirs_set ~of_:workspace_lock_dirs_set
then chosen_lock_dirs
else (
let unknown_lock_dirs =
Set.diff chosen_lock_dirs_set workspace_lock_dirs_set |> Set.to_list
in
let f x = Path.pp (Path.source x) in
User_error.raise
[ Pp.text
"The following directories are not lock directories in this workspace:"
; Pp.enumerate unknown_lock_dirs ~f
; Pp.text "This workspace contains the following lock directories:"
; Pp.enumerate workspace_lock_dirs ~f
])
;;
end
let check_pkg_management_enabled () =
Memo.run
@@
let open Memo.O in
let+ workspace = Workspace.workspace () in
match workspace.config.pkg_enabled with
| Set (_, `Enabled) | Unset -> ()
| Set (loc, `Disabled) ->
User_error.raise
~loc
[ Pp.text "Package management is disabled in workspace configuration." ]
~hints:
[ Pp.text
"To enable package management, remove the explicit (pkg disabled) setting \
from your dune-workspace file."
]
;;
|