Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,12 @@ for the given type.

1. Docs: `[@doc "Overwrites the docstring"]`, `[@docs "SECTION TWO"]`, `[@docv "VAL"]`
2. Environment variables: `[@env "ENVNAME"]`, `[@env.doc "Docs for the variable"]`, `[@env.docs "SECTION ENVS"]`
3. Other: `[@list_sep '@']`, `[@default 123]`, `[@enum [("a", Foo); ("b", Bar)]]`, `[@aka ["b";"another-flag-name"]]`, `[@conv cmdliner_converter]` (cf. [required argument to `conv`](http://erratique.ch/software/cmdliner/doc/Cmdliner.Arg.html#VALconv) in Cmdliner), `[@opt_all]` only on `a' list` fields, `[@term cmdliner_term]` for assiging an arbitrary `Cmdliner.Term.t` to a field.
3. Other:
* `[@list_sep '@']`
* `[@default 123]` (default value)
* `[@enum [("a", Foo); ("b", Bar)]]` (custom parser for values)
* `[@aka ["b";"another-flag-name"]]` (aliases for the flag)
* `[@conv cmdliner_converter]` (custom converter; cf. [required argument to `conv`](http://erratique.ch/software/cmdliner/doc/Cmdliner.Arg.html#VALconv) in Cmdliner)
* `[@opt_all]` only on `a' list` fields
* `[@pos_all]` (all positional arguments; only on `'a list` fields)
* `[@term cmdliner_term]` for assiging an arbitrary `Cmdliner.Term.t` to a field.
20 changes: 15 additions & 5 deletions src/ppx_deriving_cmdliner.ml
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ let rec docv_for ?list_sep typ =



let info_for ?pos ~attrs ~name ?list_sep ~typ ~env =
let info_for ~is_pos ~attrs ~name ?list_sep ~typ ~env =
let loc = typ.ptyp_loc in
let name' = match attr_string_opt "name" attrs with
| None -> str (clize_flag name)
Expand All @@ -173,9 +173,10 @@ let info_for ?pos ~attrs ~name ?list_sep ~typ ~env =
| Some d -> str d in
let doc' = attr_string_opt "ocaml.doc" attrs |> expr_opt ~loc ~kind:str in
let docs' = attr_string_opt "docs" attrs |> expr_opt ~loc ~kind:str in
let names = match pos with
| None -> [%expr [%e name'] :: [%e aka]]
| Some _ -> [%expr []]
let names = if is_pos then
[%expr []]
else
[%expr [%e name'] :: [%e aka]]
in
[%expr info ?env:[%e env]
?docs:[%e docs'] ?doc:[%e doc'] ~docv:[%e docv'] [%e names]]
Expand All @@ -199,7 +200,8 @@ let rec ser_expr_of_typ typ attrs name =
| Some conv -> conv
in
let pos = attr_int_opt "pos" attrs in
let info' = info_for ?pos ~attrs ~name ?list_sep ~typ ~env:env' in
let is_pos = pos<>None || key_attr_exists attrs "pos_all" in
let info' = info_for ~is_pos ~attrs ~name ?list_sep ~typ ~env:env' in
match typ with
| _ when value_attr_exists attrs "term" ->
attr_expr_exn attrs "term"
Expand Down Expand Up @@ -247,6 +249,14 @@ let rec ser_expr_of_typ typ attrs name =
| Some d -> [%expr
Cmdliner.Arg.(value & opt_all [%e conv'] [%e d] & [%e info'])]
end

| [%type: [%t? typ] list]
when key_attr_exists attrs "pos_all" ->
let conv' = match attr_expr attrs "conv" with
| None -> converter_for ?list_sep ?enum:(attr_expr attrs "enum") typ
| Some conv -> conv
in
[%expr Cmdliner.Arg.(value & pos_all [%e conv'] [] & [%e info'])]
| [%type: unit] -> failwith "`unit` is not supported in Ppx_deriving_cmdliner"
| [%type: int] | [%type: int32] | [%type: Int32.t] | [%type: int64]
| [%type: Int64.t] | [%type: nativeint] | [%type: Nativeint.t]
Expand Down
19 changes: 18 additions & 1 deletion test/test_ppx_deriving_cmdliner.ml
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,19 @@ let miscs () =
~term:(misc_types_cmdliner_term ())
~argv ~expected ~pprinter:pp_misc_types

type pos_all = {
files: string list [@pos_all];
debug: bool;
}
[@@deriving cmdliner, show]

let pos_all ()=
let argv = [|"cmd"; "a"; "b"; "--debug"; "c"; "d"|] in
let expected = {files=["a"; "b"; "c"; "d"]; debug=true} in
cmd_test_case "expected pos_all to work"
~term:(pos_all_cmdliner_term ())
~argv ~expected ~pprinter:pp_pos_all

let test_set =
[ ("simple types", `Quick, simple)
; ("default types", `Quick, defaults)
Expand All @@ -241,6 +254,10 @@ let test_set =
; ("custom types", `Quick, customs)
; ("opt_all type", `Quick, opt_all)
; ("term type", `Quick, terms)
; ("misc types", `Quick, miscs) ]
; ("misc types", `Quick, miscs)
; ("pos_all", `Quick, pos_all)

]


let () = Alcotest.run "Ppx_deriving_cmdliner" [("test", test_set)]