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
type unlocked = OpamStateTypes.unlocked
type 'a sw = 'a OpamStateTypes.switch_state
let setup () =
OpamFormatConfig.init ();
OpamCoreConfig.init ~safe_mode:true ();
let root = OpamStateConfig.opamroot () in
let _cfg = OpamStateConfig.load_defaults ~lock_kind:`Lock_none root in
ignore _cfg
let with_switch_state f =
setup ();
match
OpamGlobalState.with_ `Lock_none @@ fun gt ->
OpamSwitchState.with_ `Lock_none gt f
with
| result -> Ok result
| exception exn -> Error (`Msg (Printexc.to_string exn))
let libdir ~sw name =
let root = sw.OpamStateTypes.switch_global.OpamStateTypes.root in
let switch = sw.OpamStateTypes.switch in
let cfg = sw.OpamStateTypes.switch_config in
Fpath.v
(OpamFilename.Dir.to_string (OpamPath.Switch.lib root switch cfg name))
let package_of_name ~sw name =
OpamPackage.Set.find_opt
(fun p -> OpamPackage.Name.equal (OpamPackage.name p) name)
sw.OpamStateTypes.installed
let depends ~sw name =
let installed = OpamPackage.names_of_packages sw.OpamStateTypes.installed in
match package_of_name ~sw name with
| None -> OpamPackage.Name.Set.empty
| Some pkg ->
let opam = OpamSwitchState.opam sw pkg in
let formula =
OpamFilter.filter_deps ~build:false ~post:false ~test:false ~doc:false
~dev_setup:false ~dev:false ~default:true
(OpamFile.OPAM.depends opam)
in
let deps =
OpamFormula.fold_left
(fun acc (n, _) -> OpamPackage.Name.Set.add n acc)
OpamPackage.Name.Set.empty formula
in
OpamPackage.Name.Set.inter deps installed
let opam_packages_of_meta_dirs ~sw meta_dirs =
let root = sw.OpamStateTypes.switch_global.OpamStateTypes.root in
let switch = sw.OpamStateTypes.switch in
let cfg = sw.OpamStateTypes.switch_config in
let meta_dir_strs =
List.map (fun p -> Fpath.to_string (Fpath.to_dir_path p)) meta_dirs
in
OpamPackage.Set.fold
(fun pkg acc ->
let name = OpamPackage.name pkg in
let lib_dir = OpamPath.Switch.lib root switch cfg name in
let lib_s = OpamFilename.Dir.to_string lib_dir ^ "/" in
let matches =
List.exists
(fun meta_s ->
String.length meta_s >= String.length lib_s
&& String.sub meta_s 0 (String.length lib_s) = lib_s
|| meta_s = lib_s)
meta_dir_strs
in
if matches then OpamPackage.Name.Set.add name acc else acc)
sw.OpamStateTypes.installed OpamPackage.Name.Set.empty
let package_names_of_meta_dirs ~sw meta_dirs =
opam_packages_of_meta_dirs ~sw meta_dirs
|> OpamPackage.Name.Set.elements
|> List.map OpamPackage.Name.to_string