package unic

  1. Overview
  2. Docs
A tool to infer what is needed to vendors to compile unikernels

Install

dune-project
 Dependency

Authors

Maintainers

Sources

uniq-0.1.0.tbz
sha256=998588f1053cf03161a4bded6d7f8068c88de497e77fc0bbca81a5234fa444d5
sha512=53d4ee5ad8c01e19a2e1fbda86266768d118f78566b82f0c736338ce2c12258185a5f4dbb90bf0da37a7528098266ec81861bdcfea29e55daa3122a4f3a1daca

doc/src/unic.info/unic_info.ml.html

Source file unic_info.ml

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
let error_msgf fmt = Fmt.kstr (fun msg -> Error (`Msg msg)) fmt

let show quiet location =
  match Uniq_info.v location with
  | Ok t ->
      if not quiet then Uniq_info.show Fmt.stdout t;
      `Ok 0
  | Error (`Msg msg) ->
      if quiet then `Ok 1 else `Error (false, Fmt.str "%s." msg)

let search quiet filters prefer_library roots modname digest =
  match Uniq_mod.search ~filters ~roots modname digest with
  | Ok [] -> `Ok 1
  | Ok modules ->
      let fn (_, m) = Uniq_info.is_a_library m in
      let modules =
        if prefer_library then
          match List.filter fn modules with
          | [] -> modules
          | libraries -> libraries
        else modules
      in
      List.iter (fun (path, _) -> Fmt.pr "%a\n%!" Fpath.pp path) modules;
      `Ok 0
  | Error (`Msg msg) ->
      if quiet then `Ok 1 else `Error (false, Fmt.str "%s." msg)

open Cmdliner
open Unic_cli

let file =
  let doc = "The OCaml object." in
  let parser str =
    match Fpath.of_string str with
    | Ok _ as v when Sys.file_exists str && Sys.is_directory str = false -> v
    | Ok v -> error_msgf "%a is not a file or does not exist" Fpath.pp v
    | Error _ as err -> err
  in
  let existing_file = Arg.conv (parser, Fpath.pp) in
  Arg.(required & pos ~rev:true 0 (some existing_file) None & info [] ~doc)

let term_show =
  let open Term in
  ret (const show $ setup_logs $ file)

let cmd_show =
  let doc = "Print information about an OCaml object." in
  let man =
    [
      `S Manpage.s_description
    ; `P
        "$(tname) reads an OCaml object (a $(b,.cmi), $(b,.cmo), $(b,.cmx), \
         $(b,.cma) or $(b,.cmxa) file) and prints what the object exports and \
         what it imports, with the digest of each module."
    ]
  in
  Cmd.v (Cmd.info "show" ~doc ~man) term_show

let directories =
  let doc = "The directory containing the OCaml files." in
  let parser str =
    match Fpath.of_string str with
    | Ok _ as v when Sys.file_exists str && Sys.is_directory str -> v
    | Ok v -> error_msgf "%a is not a directory or does not exist" Fpath.pp v
    | Error _ as err -> err
  in
  let open Arg in
  value
  & opt_all (conv (parser, Fpath.pp)) []
  & info [ "I" ] ~doc ~docv:"DIRECTORY"

let modpath =
  let doc = "The module name." in
  let parser str =
    let p = String.split_on_char '.' str in
    let fn acc str =
      match (acc, Modname.of_string str) with
      | (Error _ as err), _ -> err
      | _, (Error _ as err) -> err
      | Ok rpath, Ok m -> Ok (m :: rpath)
    in
    let ( let* ) = Result.bind in
    let* lst = List.fold_left fn (Ok []) p in
    let lst = List.rev lst in
    Ok (Uniq_info.Path.of_list lst)
  in
  let pp = Uniq_info.Path.pp in
  let v = Arg.conv (parser, pp) in
  let open Arg in
  required & pos 0 (some v) None & info [] ~doc ~docv:"MODNAME"

let digest =
  let doc = "The $(i,digest) of the module." in
  let digest = Arg.conv Uniq_digest.(of_string, pp) in
  let open Arg in
  value & opt (some digest) None & info [ "digest" ] ~doc ~docv:"DIGEST"

let kind_of_artifacts =
  let intf =
    let doc = "Select only interfaces." in
    let info = Arg.info [ "intf" ] ~doc in
    (`Intf, info)
  in
  let impl =
    let doc = "Select only implementations." in
    let info = Arg.info [ "impl" ] ~doc in
    (`Impl, info)
  in
  let open Arg in
  value & vflag `All [ intf; impl ]

let kind_of_objects =
  let sources =
    let doc = "Select only source files." in
    let info = Arg.info [ "sources" ] ~doc in
    (`Sources, info)
  in
  let objects =
    let doc = "Select only object files." in
    let info = Arg.info [ "objects" ] ~doc in
    (`Objects, info)
  in
  let open Arg in
  value & vflag `All [ sources; objects ]

let target =
  let native =
    let doc = "Select only native objects." in
    let info = Arg.info [ "native" ] ~doc in
    (`Native, info)
  in
  let bytecode =
    let doc = "Select only bytecode objects." in
    let info = Arg.info [ "bytecode" ] ~doc in
    (`Bytecode, info)
  in
  let open Arg in
  value & vflag `All [ native; bytecode ]

let prefer_library =
  let doc = "Prefer libraries (.cma & .cmxa) instead of unit modules." in
  let open Arg in
  value & flag & info [ "prefer-library" ] ~doc

let setup_filters kind_artifacts kind_objects target =
  (kind_artifacts, kind_objects, target)

let setup_filters =
  let open Term in
  const setup_filters $ kind_of_artifacts $ kind_of_objects $ target

let term_search =
  let open Term in
  ret
    begin
      const search
      $ setup_logs
      $ setup_filters
      $ prefer_library
      $ setup_ocamlfind
      $ modpath
      $ digest
    end

let cmd_search =
  let doc = "Search a module from a module name and a $(i,digest)." in
  let man =
    [
      `S Manpage.s_description
    ; `P
        "$(tname) searches, into the $(b,ocamlfind) directories, the OCaml \
         objects which provide the given module. If a digest is given (see the \
         $(b,--digest) option and $(b,unic digest)), only the objects which \
         export the module with this digest are printed."
    ; `P
        "Some filters are available to restrict the search to interfaces or \
         implementations, to sources or objects, and to native or bytecode \
         objects."
    ]
  in
  Cmd.v (Cmd.info "search" ~doc ~man) term_search

let cmd =
  let doc = "A tool to manipulate OCaml objects." in
  let man =
    [
      `S Manpage.s_description
    ; `P
        "$(tname) offers some tools to inspect OCaml objects: $(b,show) prints \
         what an object exports and imports, and $(b,search) finds which \
         objects provide a given module."
    ]
  in
  let default = Term.(ret (const (`Help (`Pager, None)))) in
  Cmd.group ~default (Cmd.info "info" ~doc ~man) [ cmd_show; cmd_search ]