Suppose I have a dune project and therein an executable. Now suppose I add a new library as a dependency, eg fmt
:
(executable
(name foo)
(libraries fmt))
Theoretically, dune should be able to tell that this dependency is not mentioned in the dune-project
file and add it for me:
(package
(name ...)
(depends
fmt))
Obviously, it doesn’t do that today. But I’m wondering if there are any plans for dune to be able to do this?
In your example, the executable does not belong to any package. So how would dune determine which package to add the fmt dependency?
My bad. In my example, let’s say the package name is foo
:
(package
(name foo))
This is the common case and dune knows that the executable foo
is in the package foo
, right?
not without a public_name
, or alternatively a (package ..)
field.
OK, fair enough. Then in those two cases dune does know which package to update. Now the next problem I guess is knowing what name to insert into the depends
field for a given name in the libraries
field?
I was curious to know whether this use case was handled by opam-dune-lint so I tried. Starting from the files @yawaramin provided, tweaked as recommended:
$ cat bin/dune
(executable
(name foo)
(package foo)
(public_name foo)
(libraries fmt))
$ cat dune-project
(lang dune 3.15)
(name foo)
(generate_opam_files)
(package
(name foo))
here is the result I got: opam-dune-lint suggested to add the missing dep to both dune-project
and foo.opam
.
$ opam-dune-lint
foo.opam: changes needed:
"fmt" {>= "0.9.0"} [from bin]
Note: version numbers are just suggestions based on the currently installed version.
Write changes? [y] y
Wrote "dune-project"
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: dune-project
modified: foo.opam
no changes added to commit (use "git add" and/or "git commit -a")
$ git diff
diff --git a/dune-project b/dune-project
index e2bb6c5..79fe6d3 100644
--- a/dune-project
+++ b/dune-project
@@ -5,4 +5,7 @@
(generate_opam_files)
(package
- (name foo))
+ (name foo)
+ (depends
+ (fmt
+ (>= 0.9.0))))
\ No newline at end of file
diff --git a/foo.opam b/foo.opam
index da7cd6d..0ffd340 100644
--- a/foo.opam
+++ b/foo.opam
@@ -2,6 +2,7 @@
opam-version: "2.0"
depends: [
"dune" {>= "3.15"}
+ "fmt" {>= "0.9.0"}
"odoc" {with-doc}
]
build: [
3 Likes
Wow this is great! If dune shipped with this functionality (eg dune lint
) it would be super helpful.
Beware that opam-dune-lint infers the constraints from the versions installed in the current opam switch, so if you add a dependency for an uninstalled package it’ll infer >= 0
. But yeah, this tool is a nice QoL improvement.
1 Like
Yeah. Shouldn’t be too difficult, I think, to query the local copy of opam-repository to grab the latest available version.
The problem is that adding such a thing to Dune poses a number of issues:
- We don’t know which package the dependency belongs to in the general case
- We don’t know the opam package name for a given findlib library in the general case
- We don’t know the opam package name for a binary that is e.g. used in
run
actions in the general case
- Adding a
library
and a dependency
would be nice if the source code refers to an unknown module, but again, we don’t know what findlib
library a module belongs to in the general case
Adding a tool as part of Dune that breaks down in a lot of not very exotic cases is not great, especially as opam-dune-lint
shows that for people wanting a tool that can handle the simple cases can be done outside of Dune as it doesn’t need any Dune-specific functionality (except for maybe the case where the dune
file is not in S-expression format and one would need to build and execute it to determine what the actual dependencies are, this is some information that Dune could potentially provide to an external tool).