You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
maybe` ocaml-protoc should also ship with a small binary
(ocaml-protoc-genrules?) that takes a list of .proto files as arguments as well
as arguments for ocaml-protoc itself, and spits out a dune.inc file that
contains the rules for these particular modules? Like:
ocaml-protoc-genrules
foo.proto bar.proto --pp --binary -I dir
produces a file with:
; dune.inc
(rule
(targets foo.ml foo.mli)
(deps (:file foo.proto))
(action ocaml-protoc %{file} --pp --binary --ml_dir=.))
; … same for bar
What do you think?
Here is my response:
I support this idea. In fact, I've implemented a similar concept in a project of
mine, calling it "protoc-helper". At the time, I didn't consider proposing it
for upstream inclusion, but having something like that in the distribution
makes sense to me.
My implementation cannot be directly reusable due to its dependency footprint,
but I'm including it here as a data point.
let main =Command.basic
~summary:"generate dune stanza for all *.proto files present in the directory"
(let%map_open.Command exclude =
flag
"--exclude"
(optional_with_default [] (Arg_type.comma_separated string))
~doc:"FILE[,..]* file to exclude"infun() ->
Eio_main.run
@@funenv ->
let files =Auto_format.find_files_in_cwd_by_extensions
~cwd:(Eio.Stdenv.fs env)
~extensions:[ ".proto" ]
|>List.filter ~f:(funfile -> not (List.mem exclude file ~equal:String.equal))
inletgenerate_rule~file=letopenSexpinletlists=List s
andatoms=Atom s inlet basename =Fpath.rem_ext (Fpath.v file) inlet include_services =String.is_suffix (Fpath.to_string basename) ~suffix:"_service"inlist
[ atom "rule"
; list
[ atom "targets"
; atom (Fpath.add_ext "ml" basename |>Fpath.to_string)
; atom (Fpath.add_ext "mli" basename |>Fpath.to_string)
]
; list [ atom "deps"; list [ atom "glob_files"; atom "*.proto" ] ]
; list
[ atom "action"
; list
[ atom "run"
; atom "ocaml-protoc"
; atom file
; atom "--binary"
; (if include_services then atom "--services"else atom "--yojson")
; atom "--ml_out"
; atom "."
]
]
]
inEio_writer.with_flow (Eio.Stdenv.stdout env)
@@funstdout ->
Eio_writer.printf
stdout
"; dune file generated by '%s' -- do not edit.\n"
(Sys.get_argv ()|>Array.to_list
|>List.mapi ~f:(funis -> if i =0thenFpath.v s |>Fpath.basename else s)
|>String.concat ~sep:"");
List.iter files ~f:(funfile -> Eio_writer.print_s stdout (generate_rule ~file)))
;;
Note: I used dune format-dune-file to avoid worrying about formatting during
generation. This requires the pipe-stdout construct, introduced in dune.2.7,
so may need to update your dune-project config to use it.
I suspect that the dependency computation in my implementation might be flawed.
I was concerned about whether the compiler needed to revisit a file, say dep.proto, while compiling another file, a.proto, that depends on dep.proto. As a result, I made all invocations depend on all proto files
systematically. This might be an overkill and potentially unnecessary.
The text was updated successfully, but these errors were encountered:
Indeed I was more thinking of something without dependencies (besides the ocaml-protoc compiler-libs perhaps). :-).
I suspect it'd be possible to use the ocaml-protoc compiler-libs to compute the actual dependencies based on import statements. But it's starting to be some work.
Why not just glob proto files in dune recursively (typically they are organized as a hierarchy corresponding to package names etc), and produce one output by ocaml-protoc as the result, with all the modules scoped by corresponding packages/filenames?
I'm quoting an exchange we had with Simon in #231:
@c-cube:
Here is my response:
I support this idea. In fact, I've implemented a similar concept in a project of
mine, calling it "protoc-helper". At the time, I didn't consider proposing it
for upstream inclusion, but having something like that in the distribution
makes sense to me.
My implementation cannot be directly reusable due to its dependency footprint,
but I'm including it here as a data point.
Here's how it can be used in a dune file:
Note: I used
dune format-dune-file
to avoid worrying about formatting duringgeneration. This requires the
pipe-stdout
construct, introduced indune.2.7
,so may need to update your dune-project config to use it.
I suspect that the dependency computation in my implementation might be flawed.
I was concerned about whether the compiler needed to revisit a file, say
dep.proto
, while compiling another file,a.proto
, that depends ondep.proto
. As a result, I made all invocations depend on all proto filessystematically. This might be an overkill and potentially unnecessary.
The text was updated successfully, but these errors were encountered: