Howdy, I’m wanting to include the version of my package in a command line app I wrote and a quick search on github shows there’s a Dune_project.version. I asked GPT about this and it told me to add (version X.X.X) to my dune-project file, then be sure to have (public_name <NAME>) in my lib/bin dune files. I’ve done this but I still get an unbound module error. What is the canonical way of getting package version information into bin/lib so it can be accessed?
AFAIK, the blessed way to include version information in dune is via dune subst
Somehow this feels wrong
I was hoping there was a way similar to how cargo handles the version in the package info.
if it makes you feel better it reminds me most of an old Subversion feature: https://svnbook.red-bean.com/en/1.6/svn.advanced.props.special.keywords.html e.g. $Revision$ in files.
Hm, perhaps this is an opportunity to just write something. I assume there is a an existing lib for parsing a dune file?
In case it feels better, you could do something like this:
$ cat dune-project | rg package -A 5
(package
(name foo)
(version 1.1)
(synopsis "Short description")
(description "Longer description")
(depends
$ tree version/
version/
└── dune
1 directory, 1 file
$ cat version/dune
(library
(name version))
(rule
(action
(with-stdout-to
version.ml
(run echo "let v = \"%{version:foo}\""))))
$ tree bin/
bin/
├── dune
└── foo.ml
1 directory, 2 files
$ cat bin/dune
(executable
(public_name foo)
(libraries version))
↳[0]
$ cat bin/foo.ml
let () = print_endline Version.v
$ dune exec foo
1.1
using the version:<package> variable documented at Variables - Dune documentation
The dune subst approach feels right to me, so it’s not clear to me how to motivate a need for this, but you could of course write something if you feel motivated! You could also start a discussion on the dune repo if you think there’s a good case to be made for this kind of addition.
Ah yeah I saw this too but it also feels a bit wrong. I was really hoping for something akin to the cargo package parsing that happens in the clap crate. It just parses the toml and gets the version from there at compile time without needing to substitute a string, or run commands to generate code. If it makes life easier for someone (even if that someone is just me), I think it’s worth writing a small utility that does the same.
Follow your heart ![]()
So this might actually be doable. Since dune knows the version, and there is a library ppxlib with a function ppx_get_env which can read an environment variable and expand the macro into a string at compile time. If there’s a way to set the environment variable from dune’s end (maybe a rule, I’m not super familiar with dune yet) and then use ppxlib to get that environment variable, it avoids needing the extra file and I can get the version from the dune-project as a singular source of truth for the version. There’s also an example repo with a deriver, which would be cool to then use on cmdliner’s Cmd.Info to auto-derive the version. This is probably as close to the rust/cargo/clap way of doing it as I imagine I will get. In rust you can just do:
use clap::{Command, Parser};
#[derive(Debug, Clone, Parser)]
#[command(version)]
struct MyCommand;
And this will just get the version from the Cargo.toml
[package]
version = "0.1.0"
...
I think there’s a few things it can automatically get from the Cargo.toml, so maybe once I get the version portion working I will also include other derivers.
OK, well. Unfortunately, %{version:<pkg>} is only available through actions. You can set environment variables that way, but I don’t think it will make it to the compiler in time. ![]()
Perhaps the only way would either to see if dune is willing to make the project metadata available at compile time, then something similar to this would be possible: macros.rs - source
Or maybe there is another way, but I’m not sure.
There is the dune-build-info library: Dune Libraries - Dune documentation
Ah cool, thank you. I just opened a discussion on the dune repo Consider `dune-project` environment variables · ocaml/dune · Discussion #13329 · GitHub but I will try this for the time being.
For the time being I ended up using dune-build-info to get the version information (though other information would also be nice to have) and on the nix side I wrote this parser which makes it much easier to set it and forget it on the nix side of things.