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
|
open Import
open Pkg_common
let find_outdated_packages ~transitive ~lock_dirs_arg () =
let open Fiber.O in
let+ pps, not_founds =
let* workspace = Memo.run (Workspace.workspace ()) in
Pkg_common.Lock_dirs_arg.lock_dirs_of_workspace lock_dirs_arg workspace
|> Fiber.parallel_map ~f:(fun lock_dir_path ->
(* updating makes sense when checking for outdated packages *)
let* repos =
get_repos
(repositories_of_workspace workspace)
~repositories:(repositories_of_lock_dir workspace ~lock_dir_path)
and+ local_packages = Memo.run find_local_packages
and+ platform = solver_env_from_system_and_context ~lock_dir_path in
let lock_dir = Dune_pkg.Lock_dir.read_disk_exn lock_dir_path in
let packages =
Dune_pkg.Lock_dir.Packages.pkgs_on_platform_by_name lock_dir.packages ~platform
in
let+ results = Dune_pkg.Outdated.find ~repos ~local_packages packages in
( Dune_pkg.Outdated.pp ~transitive ~lock_dir_path results
, ( Dune_pkg.Outdated.packages_that_were_not_found results
|> Package_name.Set.of_list
|> Package_name.Set.to_list
, lock_dir_path
, repos ) ))
>>| List.split
in
(match pps with
| [ _ ] -> Console.print pps
| _ -> Console.print [ Pp.enumerate ~f:Fun.id pps ]);
let error_messages =
List.filter_map not_founds ~f:(function
| [], _, _ -> None
| packages, lock_dir_path, repos ->
Pp.concat
~sep:Pp.space
[ Pp.textf
"When checking %s, the following packages:"
(Path.Source.to_string_maybe_quoted lock_dir_path)
|> Pp.hovbox
; Pp.concat
~sep:Pp.space
[ Pp.enumerate packages ~f:(fun name ->
Dune_lang.Package_name.to_string name |> Pp.verbatim)
; Pp.text "were not found in the following opam repositories:" |> Pp.hovbox
; Pp.enumerate repos ~f:(fun repo ->
(* CR-rgrinberg: why are we outputting [Dyn.t] in error
messages? *)
Dune_pkg.Opam_repo.serializable repo
|> Dyn.option Dune_pkg.Opam_repo.Serializable.to_dyn
|> Dyn.pp)
]
|> Pp.vbox
]
|> Pp.hovbox
|> Option.some)
in
match error_messages with
| [] -> ()
| error_messages ->
User_error.raise (Pp.text "Some packages could not be found." :: error_messages)
;;
let term =
let+ builder = Common.Builder.term
and+ transitive =
Arg.(
value
& flag
& info
[ "transitive" ]
~doc:"Check for outdated packages in transitive dependencies")
and+ lock_dirs_arg = Pkg_common.Lock_dirs_arg.term in
let builder = Common.Builder.forbid_builds builder in
let common, config = Common.init builder in
Scheduler.go_with_rpc_server ~common ~config
@@ find_outdated_packages ~transitive ~lock_dirs_arg
;;
let info =
let doc = "Check for outdated packages" in
let man =
[ `S "DESCRIPTION"
; `P
"List packages in from lock directory that have newer versions available. By \
default, only direct dependencies are checked. The $(b,--transitive) flag can \
be used to check transitive dependencies as well."
; `P "For example:"
; `Pre " \\$ dune pkg outdated"
; `Noblank
; `Pre " 1/2 packages in dune.lock are outdated."
; `Noblank
; `Pre " - ocaml 4.14.1 < 5.1.0"
; `Noblank
; `Pre " - dune 3.7.1 < 3.11.0"
]
in
Cmd.info "outdated" ~doc ~man
;;
let command = Cmd.v info term
|