Skip to content

Commit 36a04ba

Browse files
authored
adds YAML as an alternative output of the specification command (#1295)
Motivation: YAML is both human-readable and machine-readbale and together with yq it is possible to easily construct various queries or translate it to json and other formats. Also adds a corresponding `Ogre.Doc.pp_yaml` function.
1 parent 59d2132 commit 36a04ba

File tree

3 files changed

+66
-8
lines changed

3 files changed

+66
-8
lines changed

lib/ogre/ogre.ml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,45 @@ module Doc = struct
380380
let pp ppf t =
381381
fprintf ppf "%a@\n%a" pp_scheme t pp_body t
382382

383+
module Yaml = struct
384+
let pp_typ ppf typ =
385+
pp_print_string ppf (Type.string_of_typ typ)
386+
387+
let pp_headers = pp_print_list
388+
~pp_sep:(fun ppf () -> pp_print_string ppf ", ")
389+
(fun ppf {Type.fname; ftype} ->
390+
fprintf ppf "%S : %a" fname pp_typ ftype)
391+
392+
let pp_scheme ppf {scheme} =
393+
fprintf ppf "scheme:@\n";
394+
Map.iteri scheme ~f:(fun ~key:n ~data:s ->
395+
fprintf ppf " %S : {%a}@\n" n pp_headers s)
396+
397+
398+
let pp_objects = pp_print_list
399+
~pp_sep:(fun ppf () -> pp_print_string ppf " ")
400+
pp_print_string
401+
402+
let pp_body ppf {scheme; entries} =
403+
Map.iteri entries ~f:(fun ~key:name ~data:entries ->
404+
fprintf ppf "%S:@\n" name;
405+
List.iter entries ~f:(fun {fields} ->
406+
let objects =
407+
List.map (Map.find_exn scheme name) ~f:(fun {fname; ftype} ->
408+
let v = Map.find_exn fields fname in
409+
match ftype with
410+
| Type.Str -> asprintf "%S: %S@\n" fname v
411+
| _ -> asprintf "%S: %s@\n" fname v) in
412+
match objects with
413+
| [] -> ()
414+
| _ -> fprintf ppf " - %a" pp_objects objects))
415+
let pp ppf doc =
416+
pp_scheme ppf doc;
417+
pp_body ppf doc
418+
end
419+
420+
let pp_yaml = Yaml.pp
421+
383422
let load channel = Or_error.try_with_join ~backtrace:true (fun () ->
384423
of_sexps (Sexp.input_sexps channel))
385424

lib/ogre/ogre.mli

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,11 @@ module Doc : sig
559559
(** [pp ppf doc] prints a [doc] in the specified formatter [ppf] *)
560560
val pp : Format.formatter -> doc -> unit
561561

562+
(** [pp_yamp ppf doc] prints doc to [ppf] in the YAML format.
563+
564+
@since 2.3.0 *)
565+
val pp_yaml : Format.formatter -> doc -> unit
566+
562567

563568
(** [clear doc] removes all facts from the document.
564569

plugins/specification/specification_main.ml

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,18 @@ type Extension.Error.t += Fail of problem
1818

1919

2020
let input = Extension.Command.argument
21-
~doc:"The input file" Extension.Type.("FILE" %: string =? "a.out" )
21+
~doc:"The input file"
22+
Extension.Type.("FILE" %: string =? "a.out")
23+
24+
let formats = [
25+
"sexp", `Sexp;
26+
"yaml", `Yaml;
27+
]
28+
29+
let format = Extension.Command.parameter
30+
(Extension.Type.enum formats) "format"
31+
~aliases:["o"]
32+
~doc:"The output format"
2233

2334
let loader =
2435
Extension.Command.parameter
@@ -34,26 +45,29 @@ let reader = Data.Read.create ()
3445
let writer = Data.Write.create ()
3546
~to_bigstring:(Binable.to_bigstring (module Ogre.Doc))
3647

48+
let print fmt spec =
49+
let pp = match fmt with
50+
| `Yaml -> Ogre.Doc.pp_yaml
51+
| `Sexp -> Ogre.Doc.pp in
52+
Format.printf "%a@\n%!" pp spec
53+
3754
let () = Extension.Command.(begin
38-
declare "specification" (args $input $loader)
55+
declare "specification" (args $format $input $loader)
3956
~doc
4057
~requires:["loader"]
41-
end) @@ fun input loader ctxt ->
58+
end) @@ fun format input loader ctxt ->
4259
let digest = Data.Cache.Digest.create ~namespace:"specification" in
4360
let digest = Data.Cache.Digest.add digest "%s%s%s"
4461
input loader (Extension.Configuration.digest ctxt) in
4562
let cache = Data.Cache.Service.request reader writer in
4663
match Data.Cache.load cache digest with
47-
| Some spec ->
48-
Format.printf "%a@\n%!" Ogre.Doc.pp spec;
49-
Ok ()
64+
| Some spec -> print format spec; Ok ()
5065
| None -> match Image.find_loader loader with
5166
| None -> problem (Unknown_loader loader)
5267
| Some (module Load) -> match Load.from_file input with
5368
| Ok (Some spec) ->
5469
Data.Cache.save cache digest spec;
55-
Format.printf "%a@\n%!" Ogre.Doc.pp spec;
56-
Ok ()
70+
print format spec; Ok ()
5771
| Ok None -> Ok ()
5872
| Error err -> problem (Loader_error err)
5973

0 commit comments

Comments
 (0)