This commit is contained in:
parent
aa2ff7b2f0
commit
2f3113f55d
11742 changed files with 1223940 additions and 0 deletions
|
|
@ -0,0 +1,26 @@
|
|||
Test that section pforms are substituted with absolute paths.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ make_lockdir
|
||||
|
||||
$ cat >dune.lock/test.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (install (progn
|
||||
> (run echo --prefix %{prefix})
|
||||
> (run echo --prefix=%{prefix})))
|
||||
> EOF
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.13)
|
||||
> (package
|
||||
> (name foo)
|
||||
> (allow_empty)
|
||||
> (depends test))
|
||||
> EOF
|
||||
|
||||
Note that currently dune incorrectly substitutes relative paths for pforms that
|
||||
appear in string interpolations.
|
||||
$ build_pkg test 2>&1 | strip_sandbox
|
||||
--prefix $SANDBOX/_private/default/.pkg/test/target
|
||||
$SANDBOX/_private/default/.pkg/test/target
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
Test that we support the use case of using additional constraints to force the
|
||||
system compiler to be used instead of installing the compiler.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
Create packages resembling the ocaml compiler packages
|
||||
$ mkrepo
|
||||
|
||||
$ mkpkg ocaml-base-compiler <<EOF
|
||||
> conflicts: [ "ocaml-system" "ocaml-variants" ]
|
||||
> EOF
|
||||
|
||||
$ mkpkg ocaml-variants <<EOF
|
||||
> conflicts: [ "ocaml-system" "ocaml-base-compiler" ]
|
||||
> EOF
|
||||
|
||||
$ mkpkg ocaml-system <<EOF
|
||||
> conflicts: [ "ocaml-variants" "ocaml-base-compiler" ]
|
||||
> EOF
|
||||
|
||||
$ mkpkg ocaml <<EOF
|
||||
> depends: [
|
||||
> "ocaml-base-compiler" | "ocaml-variants" | "ocaml-system"
|
||||
> ]
|
||||
> EOF
|
||||
|
||||
A package that depends on ocaml:
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.13)
|
||||
> (package
|
||||
> (name foo)
|
||||
> (depends ocaml))
|
||||
> EOF
|
||||
|
||||
Try solving without additional constraints:
|
||||
$ add_mock_repo_if_needed
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- ocaml.0.0.1
|
||||
- ocaml-base-compiler.0.0.1
|
||||
|
||||
Now make a workspace file adding the constarint on ocaml-system:
|
||||
$ cat >dune-workspace <<EOF
|
||||
> (lang dune 3.13)
|
||||
> (lock_dir
|
||||
> (constraints ocaml-system)
|
||||
> (repositories mock))
|
||||
> (repository
|
||||
> (name mock)
|
||||
> (url "file://$(pwd)/mock-opam-repository"))
|
||||
> EOF
|
||||
|
||||
Solve again. This time ocaml-system is chosen.
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- ocaml.0.0.1
|
||||
- ocaml-system.0.0.1
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
It's possible to include additional packages or constraints in workspace files:
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ cat >dune-workspace <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (lock_dir
|
||||
> (constraints doesnotexist foo (bar (= 1.0.0)))
|
||||
> (repositories mock))
|
||||
> (repository
|
||||
> (name mock)
|
||||
> (url "file://$(pwd)/mock-opam-repository"))
|
||||
> EOF
|
||||
|
||||
$ mkrepo
|
||||
|
||||
$ mkpkg foo 1.0.0
|
||||
$ mkpkg bar 1.0.0
|
||||
$ mkpkg bar 1.9.1
|
||||
|
||||
Notice that the constraints field doesn't introduce additional packages. The
|
||||
"doesnotexist" package isn't being pulled.
|
||||
|
||||
$ solve_project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name x)
|
||||
> (depends foo bar))
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
- bar.1.0.0
|
||||
- foo.1.0.0
|
||||
|
||||
Constraint negation is supported since 3.18:
|
||||
|
||||
$ cat >dune-workspace <<EOF
|
||||
> (lang dune 3.18)
|
||||
> (lock_dir
|
||||
> (constraints doesnotexist (foo (not (= 1.0.0))) (bar (not (= 1.0.0))))
|
||||
> (repositories mock))
|
||||
> (repository
|
||||
> (name mock)
|
||||
> (url "file://$(pwd)/mock-opam-repository"))
|
||||
> EOF
|
||||
|
||||
There are no valid version of foo at the moment:
|
||||
|
||||
$ solve_project <<EOF
|
||||
> (lang dune 3.18)
|
||||
> (package
|
||||
> (name x)
|
||||
> (depends foo bar))
|
||||
> EOF
|
||||
Error: Unable to solve dependencies for the following lock directories:
|
||||
Lock directory dune.lock:
|
||||
Couldn't solve the package dependency formula.
|
||||
Selected candidates: bar.1.9.1 x.dev
|
||||
- foo -> (problem)
|
||||
No usable implementations:
|
||||
foo.1.0.0: Package does not satisfy constraints of local package x
|
||||
[1]
|
||||
|
||||
If we add one:
|
||||
|
||||
$ mkpkg foo 0.9.0
|
||||
|
||||
$ solve_project <<EOF
|
||||
> (lang dune 3.18)
|
||||
> (package
|
||||
> (name x)
|
||||
> (depends foo bar))
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
- bar.1.9.1
|
||||
- foo.0.9.0
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
This test verifies the @pkg-install alias fetch and build the project dependencies
|
||||
without building the project itself.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
Create a project using the fake library as a dependency:
|
||||
$ cat > dune-project << EOF
|
||||
> (lang dune 3.16)
|
||||
> (package
|
||||
> (name bar)
|
||||
> (allow_empty)
|
||||
> (depends foo))
|
||||
> EOF
|
||||
|
||||
Ensure the alias is not available outside of the package manamgent context:
|
||||
$ dune build @pkg-install
|
||||
Error: The @pkg-install alias cannot be used without a lock dir
|
||||
-> required by alias pkg-install
|
||||
Hint: You might want to create the lock dir with 'dune pkg lock'
|
||||
[1]
|
||||
|
||||
Create a fake package which echoes information to stdout when build:
|
||||
$ make_lockdir
|
||||
$ cat > dune.lock/foo.pkg << EOF
|
||||
> (version 0.0.1)
|
||||
> (build
|
||||
> (run echo "Build package foo"))
|
||||
> (install
|
||||
> (run echo "Install package foo"))
|
||||
> EOF
|
||||
|
||||
Create a rule to show that this rule is not called with `@pkg-install` as `bar`
|
||||
is not build when calling the alias. If called, it would output the content of
|
||||
the `bar.ml` file:
|
||||
$ cat > dune << EOF
|
||||
> (executable
|
||||
> (name bar))
|
||||
> (rule
|
||||
> (target bar.ml)
|
||||
> (action
|
||||
> (progn
|
||||
> (with-stdout-to %{target} (echo "let _ = 42"))
|
||||
> (system "cat %{target}"))))
|
||||
> EOF
|
||||
|
||||
The alias call builds the `foo` dependency but not the project itself. It
|
||||
displays the output of the fake package but not of the `bar.exe` executable:
|
||||
$ dune build @pkg-install
|
||||
Build package foo
|
||||
Install package foo
|
||||
|
||||
If we build the executable, it only shows the content of the executable as dune
|
||||
already built the `foo` dependency when calling `@pkg-install`:
|
||||
|
||||
$ dune build ./bar.exe
|
||||
let _ = 42
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
Test that dune can handle the case where a dependency's source contains a
|
||||
symlink with a missing destination.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
Define a package foo containing a broken symlink.
|
||||
$ mkdir foo
|
||||
$ touch foo/a.txt
|
||||
$ ln -s non_existent foo/b.txt
|
||||
|
||||
Define a package bar containing a broken symlink.
|
||||
$ mkdir bar
|
||||
$ touch bar/a.txt
|
||||
$ ln -s non_existent bar/b.txt
|
||||
$ tar czf bar.tar.gz bar
|
||||
|
||||
Make a directory to contain a test project and change to it.
|
||||
$ mkdir project
|
||||
$ cd project
|
||||
|
||||
Create a lockdir for the project.
|
||||
$ mkdir dune.lock
|
||||
$ cat > dune.lock/lock.dune <<EOF
|
||||
> (lang package 0.1)
|
||||
> EOF
|
||||
|
||||
The package "foo" exercises copying package sources from a local directory.
|
||||
$ cat > dune.lock/foo.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (source
|
||||
> (fetch
|
||||
> (url
|
||||
> file:///$PWD/../foo)))
|
||||
> EOF
|
||||
|
||||
The package "bar" exercises extracting a source archive from a local file.
|
||||
$ cat > dune.lock/bar.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (source
|
||||
> (fetch
|
||||
> (url
|
||||
> file:///$PWD/../bar.tar.gz)))
|
||||
> EOF
|
||||
|
||||
The package "bar" exercises extracting a source archive from a downloaded file.
|
||||
$ cat > dune.lock/baz.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (source
|
||||
> (fetch
|
||||
> (url http://0.0.0.0:1)
|
||||
> (checksum md5=$(md5sum $PWD/../bar.tar.gz | cut -f1 -d' '))))
|
||||
> EOF
|
||||
|
||||
Set up a fake web server to serve the source archive for the package "bar".
|
||||
$ echo $PWD/../bar.tar.gz >> fake-curls
|
||||
|
||||
Make a project file that depends on all the packages.
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.17)
|
||||
> (package
|
||||
> (name x)
|
||||
> (allow_empty)
|
||||
> (depends foo bar baz))
|
||||
> EOF
|
||||
|
||||
Build the packages.
|
||||
$ build_pkg foo
|
||||
$ build_pkg bar
|
||||
$ build_pkg baz
|
||||
|
||||
All files were copied except for the broken symlinks:
|
||||
$ ls _build/_private/default/.pkg/foo/source
|
||||
a.txt
|
||||
$ ls _build/_private/default/.pkg/bar/source
|
||||
a.txt
|
||||
$ ls _build/_private/default/.pkg/baz/source
|
||||
a.txt
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
Test the error message when installing package that fails.
|
||||
|
||||
$ . ./helpers.sh
|
||||
$ make_lockdir
|
||||
$ export DUNE_DEBUG_PACKAGE_LOGS=0
|
||||
|
||||
Make a project with two packages, one successful and one that fails:
|
||||
|
||||
$ cat > dune-project << EOF
|
||||
> (lang dune 3.12)
|
||||
> EOF
|
||||
|
||||
Create a package with a failing command that throws an error:
|
||||
|
||||
$ make_lockpkg x << EOF
|
||||
> (version 0.0.1)
|
||||
> (build
|
||||
> (progn
|
||||
> (run cat i_dont_exist)))
|
||||
> EOF
|
||||
|
||||
Building the package should fail and print an error:
|
||||
|
||||
$ build_pkg x 2>&1 | sed -E 's#/.*/cat#cat#g'
|
||||
File "dune.lock/x.pkg", line 4, characters 11-14:
|
||||
4 | (run cat i_dont_exist)))
|
||||
^^^
|
||||
Error: Logs for package x
|
||||
cat: i_dont_exist: No such file or directory
|
||||
|
||||
|
||||
Create a package with a succeeding command that displays some text:
|
||||
|
||||
$ make_lockpkg y << EOF
|
||||
> (version 0.0.1)
|
||||
> (build
|
||||
> (progn
|
||||
> (run echo "Success!")))
|
||||
> EOF
|
||||
|
||||
Building the package should succeed and print no output:
|
||||
|
||||
$ build_pkg y
|
||||
|
||||
Checks the package is installed:
|
||||
|
||||
$ show_pkg_cookie y
|
||||
{ files = map {}; variables = [] }
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
Requesting to build a single package should not build unrelated things:
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ make_lockdir
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.12)
|
||||
> EOF
|
||||
|
||||
$ pkg() {
|
||||
> make_lockpkg $1 <<EOF
|
||||
> (build (run echo building $1))
|
||||
> (version dev)
|
||||
> EOF
|
||||
> }
|
||||
|
||||
These two packages are independent:
|
||||
|
||||
$ pkg foo
|
||||
$ pkg bar
|
||||
|
||||
We should only see the result of building "foo"
|
||||
|
||||
$ build_pkg foo
|
||||
building foo
|
||||
|
||||
We should only see the result of building "bar"
|
||||
|
||||
$ build_pkg bar
|
||||
building bar
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
Tests that changing the dependencies of a project cause lockdir validation to
|
||||
fail due to the dependency hash not matching the hash stored in the lockdir.
|
||||
|
||||
Dummy opam repo so we can generate lockdirs
|
||||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
$ mkpkg a <<EOF
|
||||
> EOF
|
||||
|
||||
Start with a project with a single package with no dependencies:
|
||||
$ solve_project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name foo))
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
(no dependencies to lock)
|
||||
$ cat dune.lock/lock.dune
|
||||
(lang package 0.1)
|
||||
|
||||
(repositories
|
||||
(complete false)
|
||||
(used))
|
||||
$ dune pkg validate-lockdir
|
||||
|
||||
Add a dependency to the project:
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name foo)
|
||||
> (depends a))
|
||||
> EOF
|
||||
$ dune pkg validate-lockdir
|
||||
Lockdir dune.lock does not contain a solution for local packages:
|
||||
Error: This project has at least one non-local dependency but the lockdir
|
||||
doesn't contain a dependency hash.
|
||||
An example of a non-local dependency of this project is: a
|
||||
Hint: Regenerate the lockdir by running 'dune pkg lock'
|
||||
Error: Some lockdirs do not contain solutions for local packages:
|
||||
- dune.lock
|
||||
[1]
|
||||
|
||||
Add a non-local dependency to the package:
|
||||
$ solve_project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name foo)
|
||||
> (depends a))
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
- a.0.0.1
|
||||
$ cat dune.lock/lock.dune
|
||||
(lang package 0.1)
|
||||
|
||||
(dependency_hash 7ba1cacd46bb2609d7b9735909c3b8a5)
|
||||
|
||||
(repositories
|
||||
(complete false)
|
||||
(used))
|
||||
$ dune pkg validate-lockdir
|
||||
|
||||
Add a second dependency to the project:
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name foo)
|
||||
> (depends a b))
|
||||
> EOF
|
||||
$ dune pkg validate-lockdir
|
||||
Lockdir dune.lock does not contain a solution for local packages:
|
||||
File "dune.lock/lock.dune", line 3, characters 17-49:
|
||||
Error: Dependency hash in lockdir does not match the hash of non-local
|
||||
dependencies of this project. The lockdir expects the the non-local
|
||||
dependencies to hash to:
|
||||
7ba1cacd46bb2609d7b9735909c3b8a5
|
||||
...but the non-local dependencies of this project hash to:
|
||||
d18946fdd9833ae312d309f654f11c1b
|
||||
Hint: Regenerate the lockdir by running 'dune pkg lock'
|
||||
Error: Some lockdirs do not contain solutions for local packages:
|
||||
- dune.lock
|
||||
[1]
|
||||
|
||||
Remove all dependencies from the project:
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name foo))
|
||||
> EOF
|
||||
$ dune pkg validate-lockdir
|
||||
Lockdir dune.lock does not contain a solution for local packages:
|
||||
File "dune.lock/lock.dune", line 3, characters 17-49:
|
||||
Error: This project has no non-local dependencies yet the lockfile contains a
|
||||
dependency hash: 7ba1cacd46bb2609d7b9735909c3b8a5
|
||||
Hint: Regenerate the lockdir by running 'dune pkg lock'
|
||||
Error: Some lockdirs do not contain solutions for local packages:
|
||||
- dune.lock
|
||||
[1]
|
||||
|
||||
Exercise handling invalid dependency hashes.
|
||||
$ make_lock_metadata_with_hash() {
|
||||
> cat >dune.lock/lock.dune <<EOF
|
||||
> (lang package 0.1)
|
||||
> (dependency_hash $1)
|
||||
> (repositories
|
||||
> (complete false)
|
||||
> (used))
|
||||
> EOF
|
||||
> }
|
||||
|
||||
Case where the label ("md5") is missing:
|
||||
$ make_lock_metadata_with_hash badhash
|
||||
$ dune pkg validate-lockdir
|
||||
Failed to parse lockdir dune.lock:
|
||||
File "dune.lock/lock.dune", line 2, characters 17-24:
|
||||
Error: Dependency hash is not a valid md5 hash: badhash
|
||||
|
||||
Error: Some lockdirs do not contain solutions for local packages:
|
||||
- dune.lock
|
||||
[1]
|
||||
|
||||
Case where the label is not "md5":
|
||||
$ make_lock_metadata_with_hash foo=badhash
|
||||
$ dune pkg validate-lockdir
|
||||
Failed to parse lockdir dune.lock:
|
||||
File "dune.lock/lock.dune", line 2, characters 17-28:
|
||||
Error: Dependency hash is not a valid md5 hash: foo=badhash
|
||||
|
||||
Error: Some lockdirs do not contain solutions for local packages:
|
||||
- dune.lock
|
||||
[1]
|
||||
|
||||
Case where the the hash is not a valid md5 hash:
|
||||
$ make_lock_metadata_with_hash md5=badhash
|
||||
$ dune pkg validate-lockdir
|
||||
Failed to parse lockdir dune.lock:
|
||||
File "dune.lock/lock.dune", line 2, characters 17-28:
|
||||
Error: Dependency hash is not a valid md5 hash: md5=badhash
|
||||
|
||||
Error: Some lockdirs do not contain solutions for local packages:
|
||||
- dune.lock
|
||||
[1]
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
Make sure that we verify archives of local archives
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ make_lockdir
|
||||
|
||||
$ touch foo.tar.gz
|
||||
|
||||
$ make_lockpkg foo <<EOF
|
||||
> (version 0.0.1)
|
||||
> (source
|
||||
> (fetch
|
||||
> (checksum md5=069aa55d40e548280f92af693f6c625a)
|
||||
> (url $PWD/foo.tar.gz)))
|
||||
> EOF
|
||||
|
||||
$ build_pkg foo
|
||||
File "dune.lock/foo.pkg", line 4, characters 12-48:
|
||||
4 | (checksum md5=069aa55d40e548280f92af693f6c625a)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Error: Invalid checksum, got
|
||||
md5=d41d8cd98f00b204e9800998ecf8427e
|
||||
[1]
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
Make sure we can run exes from the user's PATH variable.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
Create a directory containing a shell script and add the directory to PATH.
|
||||
$ mkdir bin
|
||||
$ cat > bin/hello <<EOF
|
||||
> #!/bin/sh
|
||||
> echo "Hello, World!"
|
||||
> EOF
|
||||
$ chmod a+x bin/hello
|
||||
$ export PATH=$PATH:$PWD/bin
|
||||
|
||||
Create a lockdir with a lockfile that runs the shell script in a build command.
|
||||
$ make_lockdir
|
||||
$ cat >dune.lock/test.pkg <<'EOF'
|
||||
> (version 0.0.1)
|
||||
> (build (run hello))
|
||||
> EOF
|
||||
|
||||
The build command is run from an environment including the custom PATH variable.
|
||||
$ build_pkg test
|
||||
Hello, World!
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
What happens if a branch has the same format as a ref?
|
||||
|
||||
$ . ../git-helpers.sh
|
||||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
$ mkpkg foo 1.0
|
||||
$ cd mock-opam-repository
|
||||
$ git init --quiet
|
||||
$ git add -A
|
||||
$ git commit --quiet -m "Initial state, foo.1.0"
|
||||
$ AMBIGUOUS_REF=c3ba68d69316351bc660679f68fdc871bfb4f2d2
|
||||
$ git switch --quiet -c $AMBIGUOUS_REF
|
||||
$ mkpkg foo 2.0
|
||||
$ git add -A
|
||||
$ git commit --quiet -m "New foo.2.0 on branch $AMBIGUOUS_REF"
|
||||
$ git switch --quiet -
|
||||
$ cd ..
|
||||
|
||||
Use this ref in a project
|
||||
|
||||
$ add_mock_repo_if_needed "git+file://$PWD/mock-opam-repository#$AMBIGUOUS_REF"
|
||||
|
||||
Depend on foo from the repo
|
||||
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.10)
|
||||
>
|
||||
> (package
|
||||
> (name bar)
|
||||
> (depends foo))
|
||||
> EOF
|
||||
|
||||
Which foo will we get?
|
||||
|
||||
$ dune pkg lock 2>&1 | head -1 | sed "s/$AMBIGUOUS_REF/\$AMBIGUOUS_REF/g"
|
||||
revision "$AMBIGUOUS_REF" not found in
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
Demonstrate that local dependencies that are marked as {with-test} can be
|
||||
included.
|
||||
|
||||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
|
||||
$ mkpkg post <<EOF
|
||||
> EOF
|
||||
$ mkpkg build <<EOF
|
||||
> EOF
|
||||
$ mkpkg dev <<EOF
|
||||
> EOF
|
||||
$ mkpkg test <<EOF
|
||||
> EOF
|
||||
$ mkpkg doc <<EOF
|
||||
> EOF
|
||||
$ mkpkg dev-setup <<EOF
|
||||
> EOF
|
||||
|
||||
Note that dune solves packages with with-doc and with-dev-setup always set to false, so
|
||||
documentation-only deps are omitted from the solution.
|
||||
|
||||
Dune will also not include dependencies marked `post` in the lock directory.
|
||||
|
||||
$ solve "(test :with-test) (doc :with-doc) (dev-setup :with-dev-setup) (dev :with-dev) (build :build) (post :post)"
|
||||
Solution for dune.lock:
|
||||
- build.0.0.1
|
||||
- test.0.0.1
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
Exercise dune resolving the post dependencies found in compiler packages.
|
||||
|
||||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
|
||||
$ cat >dune-workspace << EOF
|
||||
> (lang dune 3.16)
|
||||
> (lock_dir
|
||||
> (path dune.lock)
|
||||
> (repositories mock)
|
||||
> (solver_env
|
||||
> (os linux)))
|
||||
> EOF
|
||||
|
||||
$ mkpkg host-system-other
|
||||
|
||||
$ mkpkg system-mingw << EOF
|
||||
> available: os = "win32"
|
||||
> EOF
|
||||
|
||||
$ mkpkg ocaml << EOF
|
||||
> depends: [
|
||||
> "ocaml-base-compiler"
|
||||
> ]
|
||||
> EOF
|
||||
|
||||
This package has a dependency cycle with the "ocaml" package, broken
|
||||
by the use of post dependencies. It also contains a formula with no
|
||||
solutions when the "post" variable is set to "false" on non-windows
|
||||
systems. Opam evaluates dependency formulae with post=true and then
|
||||
does further filtering to remove post dependencies from dependency
|
||||
lists to prevent circular dependencies at package build time.
|
||||
$ mkpkg ocaml-base-compiler << EOF
|
||||
> depends: [
|
||||
> "ocaml" {post}
|
||||
> (("arch-x86_64" {os = "win32" & arch = "x86_64"} & "system-mingw" &
|
||||
> "mingw-w64-shims" {os-distribution = "cygwin" & build}) |
|
||||
> ("arch-x86_32" {os = "win32"} & "ocaml-option-bytecode-only" &
|
||||
> "system-mingw" &
|
||||
> "mingw-w64-shims" {os-distribution = "cygwin" & build}) |
|
||||
> "host-system-other" {os != "win32" & post})
|
||||
> ]
|
||||
> EOF
|
||||
|
||||
$ solve ocaml-base-compiler
|
||||
Solution for dune.lock:
|
||||
- ocaml-base-compiler.0.0.1
|
||||
|
||||
Ensure that packages can be resolved at build time. This checks that
|
||||
the dependency cycle between the "ocaml" and "ocaml-base-compiler"
|
||||
packages is successfully broken by the use of post dependencies.
|
||||
$ dune build
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
Test that dune will add checksums to lockfiles when the package has a source
|
||||
archive but no checksum. This test uses an http server to serve packages to
|
||||
test checksum generation, since we only generate checksums for packages
|
||||
downloaded from non-local sources.
|
||||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
|
||||
A file that will comprise the package source:
|
||||
|
||||
$ echo "Hello, World!" > foo.txt
|
||||
$ echo foo.txt > fake-curls
|
||||
$ PORT=1
|
||||
|
||||
$ mkpkg foo <<EOF
|
||||
> url {
|
||||
> src: "http://0.0.0.0:$PORT"
|
||||
> }
|
||||
> EOF
|
||||
|
||||
$ solve foo
|
||||
Package "foo" has source archive which lacks a checksum.
|
||||
The source archive will be downloaded from: http://0.0.0.0:1
|
||||
Dune will compute its own checksum for this source archive.
|
||||
Solution for dune.lock:
|
||||
- foo.0.0.1
|
||||
|
||||
Replace the path in the lockfile as it would otherwise include the sandbox
|
||||
path.
|
||||
$ cat dune.lock/foo.pkg
|
||||
(version 0.0.1)
|
||||
|
||||
(source
|
||||
(fetch
|
||||
(url http://0.0.0.0:1)
|
||||
(checksum md5=bea8252ff4e80f41719ea13cdf007273)))
|
||||
|
||||
(dev)
|
||||
|
||||
Now make sure we can gracefully handle the case when the archive is missing.
|
||||
Recreate the foo package with a fake port number to signal that the file will
|
||||
404:
|
||||
|
||||
$ PORT=9000
|
||||
$ mkpkg foo <<EOF
|
||||
> url {
|
||||
> src: "http://0.0.0.0:$PORT"
|
||||
> }
|
||||
> EOF
|
||||
|
||||
$ solve foo 2>&1
|
||||
Package "foo" has source archive which lacks a checksum.
|
||||
The source archive will be downloaded from: http://0.0.0.0:9000
|
||||
Dune will compute its own checksum for this source archive.
|
||||
Warning: download failed with code 404
|
||||
Solution for dune.lock:
|
||||
- foo.0.0.1
|
||||
$ cat dune.lock/foo.pkg
|
||||
(version 0.0.1)
|
||||
|
||||
(source
|
||||
(fetch
|
||||
(url http://0.0.0.0:9000)))
|
||||
|
||||
(dev)
|
||||
|
||||
Check that no checksum is computed for a local source file:
|
||||
|
||||
$ mkpkg foo <<EOF
|
||||
> url {
|
||||
> src: "$PWD/foo.txt"
|
||||
> }
|
||||
> EOF
|
||||
$ solve foo 2>&1
|
||||
Solution for dune.lock:
|
||||
- foo.0.0.1
|
||||
|
||||
Check that no checksum is computed for a local source directory:
|
||||
|
||||
$ mkdir src
|
||||
$ mkpkg foo <<EOF
|
||||
> url {
|
||||
> src: "$PWD/src"
|
||||
> }
|
||||
> EOF
|
||||
$ solve foo 2>&1
|
||||
Solution for dune.lock:
|
||||
- foo.0.0.1
|
||||
|
||||
|
||||
Create 3 packages that all share the same source url with no checksum. Dune
|
||||
will need to download each package's source archive to compute their hashes.
|
||||
Test that dune only downloads the file a single time since the source url is
|
||||
identical among the packages. The fact that the download only occurs once is
|
||||
asserted by the fact that the webserver will only serve the file a single time.
|
||||
|
||||
$ echo foo.txt >> fake-curls
|
||||
$ PORT=2
|
||||
|
||||
$ mkpkg foo <<EOF
|
||||
> url {
|
||||
> src: "http://0.0.0.0:$PORT"
|
||||
> }
|
||||
> EOF
|
||||
|
||||
$ mkpkg bar <<EOF
|
||||
> url {
|
||||
> src: "http://0.0.0.0:$PORT"
|
||||
> }
|
||||
> EOF
|
||||
|
||||
$ mkpkg baz <<EOF
|
||||
> url {
|
||||
> src: "http://0.0.0.0:$PORT"
|
||||
> }
|
||||
> EOF
|
||||
|
||||
$ solve foo bar baz
|
||||
Package "bar" has source archive which lacks a checksum.
|
||||
The source archive will be downloaded from: http://0.0.0.0:2
|
||||
Dune will compute its own checksum for this source archive.
|
||||
Package "baz" has source archive which lacks a checksum.
|
||||
The source archive will be downloaded from: http://0.0.0.0:2
|
||||
Dune will compute its own checksum for this source archive.
|
||||
Package "foo" has source archive which lacks a checksum.
|
||||
The source archive will be downloaded from: http://0.0.0.0:2
|
||||
Dune will compute its own checksum for this source archive.
|
||||
Solution for dune.lock:
|
||||
- bar.0.0.1
|
||||
- baz.0.0.1
|
||||
- foo.0.0.1
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
This test demonstrates a local package that's in the same conflict-class of a
|
||||
dependency.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ mkrepo
|
||||
$ add_mock_repo_if_needed
|
||||
|
||||
$ mkpkg conflict-class
|
||||
|
||||
$ mkpkg bar <<EOF
|
||||
> conflict-class: "ccc"
|
||||
> EOF
|
||||
|
||||
Local conflict class defined in a local package:
|
||||
|
||||
$ cat >foo.opam <<EOF
|
||||
> opam-version: "2.0"
|
||||
> depends: [ "bar" ]
|
||||
> conflict-class: "ccc"
|
||||
> EOF
|
||||
|
||||
$ cat >x.opam <<EOF
|
||||
> opam-version: "2.0"
|
||||
> depends: "foo"
|
||||
> EOF
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> EOF
|
||||
|
||||
$ dune pkg lock
|
||||
Error: Unable to solve dependencies for the following lock directories:
|
||||
Lock directory dune.lock:
|
||||
Couldn't solve the package dependency formula.
|
||||
Selected candidates: foo.dev x.dev foo&x
|
||||
- bar -> (problem)
|
||||
Rejected candidates:
|
||||
bar.0.0.1: In same conflict class (ccc) as foo
|
||||
[1]
|
||||
|
||||
Now the conflict class comes from the opam repository
|
||||
|
||||
$ mkpkg foo <<EOF
|
||||
> depends: [ "bar" ]
|
||||
> conflict-class: "ccc"
|
||||
> EOF
|
||||
|
||||
$ rm foo.opam
|
||||
|
||||
$ dune pkg lock
|
||||
Error: Unable to solve dependencies for the following lock directories:
|
||||
Lock directory dune.lock:
|
||||
Couldn't solve the package dependency formula.
|
||||
Selected candidates: foo.0.0.1 x.dev
|
||||
- bar -> (problem)
|
||||
Rejected candidates:
|
||||
bar.0.0.1: In same conflict class (ccc) as foo
|
||||
[1]
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
The solver should repsect the (conflicts) field of the (package) stanza.
|
||||
|
||||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
$ mkpkg foo 0.0.1
|
||||
$ mkpkg bar << EOF
|
||||
> depends: [ "foo" ]
|
||||
> EOF
|
||||
|
||||
The solver should say no solution rather than just ignoring the conflict.
|
||||
|
||||
$ solve_project << EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name x)
|
||||
> (allow_empty)
|
||||
> (conflicts foo)
|
||||
> (depends bar))
|
||||
> EOF
|
||||
Error: Unable to solve dependencies for the following lock directories:
|
||||
Lock directory dune.lock:
|
||||
Couldn't solve the package dependency formula.
|
||||
Selected candidates: bar.0.0.1 x.dev
|
||||
- foo -> (problem)
|
||||
No usable implementations:
|
||||
foo.0.0.1: Package does not satisfy constraints of local package x
|
||||
[1]
|
||||
|
||||
There could be more than one conflict and they can have version constraints:
|
||||
|
||||
$ mkpkg foo2 0.0.1
|
||||
$ mkpkg bar2 << EOF
|
||||
> depends: [ "foo2" ]
|
||||
> EOF
|
||||
|
||||
$ solve_project << EOF
|
||||
> (lang dune 3.11)
|
||||
> (generate_opam_files true)
|
||||
> (package
|
||||
> (name x)
|
||||
> (allow_empty)
|
||||
> (conflicts (foo (< 0.2)) (foo2 (< 0.2)))
|
||||
> (depends bar bar2))
|
||||
> EOF
|
||||
Error: Unable to solve dependencies for the following lock directories:
|
||||
Lock directory dune.lock:
|
||||
Couldn't solve the package dependency formula.
|
||||
Selected candidates: bar.0.0.1 bar2.0.0.1 x.dev
|
||||
- foo -> (problem)
|
||||
No usable implementations:
|
||||
foo.0.0.1: Package does not satisfy constraints of local package x
|
||||
- foo2 -> (problem)
|
||||
No usable implementations:
|
||||
foo2.0.0.1: Package does not satisfy constraints of local package x
|
||||
[1]
|
||||
|
||||
When conflicts are obtained from an opam file instead of a dune-project,
|
||||
the behaviour should be the same:
|
||||
|
||||
$ dune build x.opam
|
||||
$ sed -n '/conflicts/,/]/p' x.opam
|
||||
conflicts: [
|
||||
"foo" {< "0.2"}
|
||||
"foo2" {< "0.2"}
|
||||
]
|
||||
|
||||
Even though the conflicts are listed by opam without a `|` to indicate a
|
||||
disjunction, either package is problematic:
|
||||
|
||||
$ mkpkg dune 3.11
|
||||
$ echo '(lang dune 3.11)' | solve_project 2>&1 | sed -E 's/3.[0-9]+/3.XX/'
|
||||
Error: Unable to solve dependencies for the following lock directories:
|
||||
Lock directory dune.lock:
|
||||
Couldn't solve the package dependency formula.
|
||||
Selected candidates: bar.0.0.1 bar2.0.0.1 x.dev
|
||||
- dune -> dune.3.XX
|
||||
User requested = 3.XX
|
||||
- foo -> (problem)
|
||||
No usable implementations:
|
||||
foo.0.0.1: Package does not satisfy constraints of local package x
|
||||
- foo2 -> (problem)
|
||||
No usable implementations:
|
||||
foo2.0.0.1: Package does not satisfy constraints of local package x
|
||||
|
||||
Adding a new version of `foo` only resolves one conflict:
|
||||
|
||||
$ mkpkg foo 0.2
|
||||
$ echo '(lang dune 3.11)' | solve_project 2>&1 | sed -E 's/3.[0-9]+/3.XX/'
|
||||
Error: Unable to solve dependencies for the following lock directories:
|
||||
Lock directory dune.lock:
|
||||
Couldn't solve the package dependency formula.
|
||||
Selected candidates: bar.0.0.1 bar2.0.0.1 foo.0.2 x.dev
|
||||
- dune -> dune.3.XX
|
||||
User requested = 3.XX
|
||||
- foo2 -> (problem)
|
||||
No usable implementations:
|
||||
foo2.0.0.1: Package does not satisfy constraints of local package x
|
||||
|
||||
Addition of `foo2` to solve the last remaining conflict:
|
||||
|
||||
$ mkpkg foo2 0.2
|
||||
$ solve_project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
- bar.0.0.1
|
||||
- bar2.0.0.1
|
||||
- foo.0.2
|
||||
- foo2.0.2
|
||||
|
||||
Same but checking that the latest versions of `foo` and `foo2` are not selected
|
||||
due to the version constraints conflicts:
|
||||
|
||||
$ solve_project << EOF
|
||||
> (lang dune 3.11)
|
||||
> (generate_opam_files true)
|
||||
> (package
|
||||
> (name x)
|
||||
> (allow_empty)
|
||||
> (conflicts (foo (>= 0.2)) (foo2 (>= 0.2)))
|
||||
> (depends bar bar2))
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
- bar.0.0.1
|
||||
- bar2.0.0.1
|
||||
- foo.0.0.1
|
||||
- foo2.0.0.1
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
Exercise the solver on a package with a conjunction in its dependency
|
||||
constraints.
|
||||
|
||||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
|
||||
$ mkpkg a
|
||||
|
||||
$ mkpkg foo << EOF
|
||||
> depends: [
|
||||
> "a" { >= "0.0.0" & < "1.0.0" }
|
||||
> ]
|
||||
> EOF
|
||||
|
||||
$ solve foo
|
||||
Solution for dune.lock:
|
||||
- a.0.0.1
|
||||
- foo.0.0.1
|
||||
|
||||
$ cat dune.lock/foo.pkg
|
||||
(version 0.0.1)
|
||||
|
||||
(depends a)
|
||||
|
|
@ -0,0 +1,370 @@
|
|||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
|
||||
$ mkpkg standard-dune <<EOF
|
||||
> build: [
|
||||
> ["dune" "subst"] {dev}
|
||||
> [
|
||||
> "dune"
|
||||
> "build"
|
||||
> "-p"
|
||||
> name
|
||||
> "-j"
|
||||
> jobs
|
||||
> "@install"
|
||||
> "@runtest" {with-test}
|
||||
> "@doc" {with-doc}
|
||||
> ]
|
||||
> ]
|
||||
> install: [ make "install" ]
|
||||
> EOF
|
||||
|
||||
$ mkpkg with-interpolation <<EOF
|
||||
> build: [
|
||||
> [
|
||||
> "./configure"
|
||||
> "--prefix=%{prefix}%"
|
||||
> "--docdir=%{doc}%/ocaml"
|
||||
> ]
|
||||
> [make "-j%{jobs}%"]
|
||||
> ]
|
||||
> install: [make "install"]
|
||||
> EOF
|
||||
|
||||
Make sure we don't mess up percent signs that aren't part of variable interpolation syntax:
|
||||
$ mkpkg with-percent-sign <<EOF
|
||||
> build: [ "printf" "%d" "42" ]
|
||||
> EOF
|
||||
|
||||
$ mkpkg with-malformed-interpolation <<EOF
|
||||
> build: [ "./configure" "--prefix=%{prefix" ]
|
||||
> EOF
|
||||
|
||||
$ mkpkg variable-types <<EOF
|
||||
> build: [
|
||||
> ["echo" local_var]
|
||||
> ["echo" _:explicit_local_var]
|
||||
> ["echo" foo:package_var]
|
||||
> ["echo" os-family]
|
||||
> ]
|
||||
> EOF
|
||||
|
||||
Package for exercising opam filters on commands:
|
||||
$ mkpkg exercise-filters <<EOF
|
||||
> build: [
|
||||
> [ "echo" "a" ] { foo }
|
||||
> [ "echo" "b" ] { foo & bar }
|
||||
> [ "echo" "c" ] { foo & bar & baz }
|
||||
> [ "echo" "d" ] { foo | bar }
|
||||
> [ "echo" "e" ] { foo | bar & baz }
|
||||
> [ "echo" "f" ] { (foo | bar) & baz }
|
||||
> [ "echo" "b" ] { foo = bar }
|
||||
> [ "echo" "g" ] { version < "1.0" }
|
||||
> [ "echo" "h" ] { with-test & ocaml:version < "5.0.0" }
|
||||
> [ "echo" "i" ] { true }
|
||||
> [ "echo" "j" ] { ! false }
|
||||
> [ "echo" "k" ] { foo:installed }
|
||||
> [ "echo" "l" ] { foo:version < "0.4" }
|
||||
> [ "echo" "m" ] { foo+bar+baz:installed }
|
||||
> [ "echo" "n" ] { ? madeup }
|
||||
> [ "echo" "o" ] { ? installed }
|
||||
> ]
|
||||
> EOF
|
||||
|
||||
Package for exercising opam filters on terms:
|
||||
$ mkpkg exercise-term-filters <<EOF
|
||||
> build: [
|
||||
> [ "echo" "a" "b" { foo } "c" { bar & baz } ]
|
||||
> ]
|
||||
> EOF
|
||||
|
||||
Package which has boolean where string was expected. This should be caught while parsing:
|
||||
$ mkpkg filter-error-bool-where-string-expected <<EOF
|
||||
> build: [
|
||||
> [ "echo" "a" ] { foo:version < (foo = bar) }
|
||||
> ]
|
||||
> EOF
|
||||
|
||||
$ solve standard-dune with-interpolation with-percent-sign variable-types
|
||||
Solution for dune.lock:
|
||||
- standard-dune.0.0.1
|
||||
- variable-types.0.0.1
|
||||
- with-interpolation.0.0.1
|
||||
- with-percent-sign.0.0.1
|
||||
|
||||
$ cat dune.lock/standard-dune.pkg
|
||||
(version 0.0.1)
|
||||
|
||||
(install
|
||||
(run %{make} install))
|
||||
|
||||
(build
|
||||
(progn
|
||||
(when
|
||||
%{pkg-self:dev}
|
||||
(run dune subst))
|
||||
(run dune build -p %{pkg-self:name} -j %{jobs} @install)))
|
||||
|
||||
$ cat dune.lock/with-interpolation.pkg
|
||||
(version 0.0.1)
|
||||
|
||||
(install
|
||||
(run %{make} install))
|
||||
|
||||
(build
|
||||
(progn
|
||||
(run ./configure --prefix=%{prefix} --docdir=%{doc}/ocaml)
|
||||
(run %{make} -j%{jobs})))
|
||||
|
||||
$ cat dune.lock/with-percent-sign.pkg
|
||||
(version 0.0.1)
|
||||
|
||||
(build
|
||||
(run printf %d 42))
|
||||
|
||||
$ cat dune.lock/variable-types.pkg
|
||||
(version 0.0.1)
|
||||
|
||||
(build
|
||||
(progn
|
||||
(run echo %{pkg-self:local_var})
|
||||
(run echo %{pkg-self:explicit_local_var})
|
||||
(run echo %{pkg:foo:package_var})
|
||||
(run echo %{os_family})))
|
||||
|
||||
$ solve with-malformed-interpolation
|
||||
File "$TESTCASE_ROOT/mock-opam-repository/packages/with-malformed-interpolation/with-malformed-interpolation.0.0.1/opam", line 1, characters 0-0:
|
||||
Error: Encountered malformed variable interpolation while processing commands
|
||||
for package with-malformed-interpolation.0.0.1.
|
||||
The variable interpolation:
|
||||
%{prefix
|
||||
[1]
|
||||
|
||||
$ solve exercise-filters
|
||||
Solution for dune.lock:
|
||||
- exercise-filters.0.0.1
|
||||
|
||||
$ cat dune.lock/exercise-filters.pkg
|
||||
(version 0.0.1)
|
||||
|
||||
(build
|
||||
(progn
|
||||
(when
|
||||
%{pkg-self:foo}
|
||||
(run echo a))
|
||||
(when
|
||||
(and_absorb_undefined_var %{pkg-self:foo} %{pkg-self:bar})
|
||||
(run echo b))
|
||||
(when
|
||||
(and_absorb_undefined_var %{pkg-self:foo} %{pkg-self:bar} %{pkg-self:baz})
|
||||
(run echo c))
|
||||
(when
|
||||
(or_absorb_undefined_var %{pkg-self:foo} %{pkg-self:bar})
|
||||
(run echo d))
|
||||
(when
|
||||
(or_absorb_undefined_var
|
||||
%{pkg-self:foo}
|
||||
(and_absorb_undefined_var %{pkg-self:bar} %{pkg-self:baz}))
|
||||
(run echo e))
|
||||
(when
|
||||
(and_absorb_undefined_var
|
||||
(or_absorb_undefined_var %{pkg-self:foo} %{pkg-self:bar})
|
||||
%{pkg-self:baz})
|
||||
(run echo f))
|
||||
(when
|
||||
(= %{pkg-self:foo} %{pkg-self:bar})
|
||||
(run echo b))
|
||||
(when
|
||||
(< %{pkg-self:version} 1.0)
|
||||
(run echo g))
|
||||
(run echo i)
|
||||
(run echo j)
|
||||
(when
|
||||
%{pkg:foo:installed}
|
||||
(run echo k))
|
||||
(when
|
||||
(< %{pkg:foo:version} 0.4)
|
||||
(run echo l))
|
||||
(when
|
||||
(and %{pkg:foo:installed} %{pkg:bar:installed} %{pkg:baz:installed})
|
||||
(run echo m))))
|
||||
|
||||
Test that if opam filter translation is disabled the output doesn't contain any translated filters:
|
||||
$ solve exercise-filters
|
||||
Solution for dune.lock:
|
||||
- exercise-filters.0.0.1
|
||||
$ cat dune.lock/exercise-filters.pkg
|
||||
(version 0.0.1)
|
||||
|
||||
(build
|
||||
(progn
|
||||
(when
|
||||
%{pkg-self:foo}
|
||||
(run echo a))
|
||||
(when
|
||||
(and_absorb_undefined_var %{pkg-self:foo} %{pkg-self:bar})
|
||||
(run echo b))
|
||||
(when
|
||||
(and_absorb_undefined_var %{pkg-self:foo} %{pkg-self:bar} %{pkg-self:baz})
|
||||
(run echo c))
|
||||
(when
|
||||
(or_absorb_undefined_var %{pkg-self:foo} %{pkg-self:bar})
|
||||
(run echo d))
|
||||
(when
|
||||
(or_absorb_undefined_var
|
||||
%{pkg-self:foo}
|
||||
(and_absorb_undefined_var %{pkg-self:bar} %{pkg-self:baz}))
|
||||
(run echo e))
|
||||
(when
|
||||
(and_absorb_undefined_var
|
||||
(or_absorb_undefined_var %{pkg-self:foo} %{pkg-self:bar})
|
||||
%{pkg-self:baz})
|
||||
(run echo f))
|
||||
(when
|
||||
(= %{pkg-self:foo} %{pkg-self:bar})
|
||||
(run echo b))
|
||||
(when
|
||||
(< %{pkg-self:version} 1.0)
|
||||
(run echo g))
|
||||
(run echo i)
|
||||
(run echo j)
|
||||
(when
|
||||
%{pkg:foo:installed}
|
||||
(run echo k))
|
||||
(when
|
||||
(< %{pkg:foo:version} 0.4)
|
||||
(run echo l))
|
||||
(when
|
||||
(and %{pkg:foo:installed} %{pkg:bar:installed} %{pkg:baz:installed})
|
||||
(run echo m))))
|
||||
|
||||
$ solve exercise-term-filters
|
||||
Solution for dune.lock:
|
||||
- exercise-term-filters.0.0.1
|
||||
$ cat dune.lock/exercise-term-filters.pkg
|
||||
(version 0.0.1)
|
||||
|
||||
(build
|
||||
(run
|
||||
echo
|
||||
a
|
||||
(when
|
||||
(catch_undefined_var %{pkg-self:foo} false)
|
||||
b)
|
||||
(when
|
||||
(catch_undefined_var
|
||||
(and_absorb_undefined_var %{pkg-self:bar} %{pkg-self:baz})
|
||||
false)
|
||||
c)))
|
||||
|
||||
$ solve filter-error-bool-where-string-expected
|
||||
File "$TESTCASE_ROOT/mock-opam-repository/packages/filter-error-bool-where-string-expected/filter-error-bool-where-string-expected.0.0.1/opam", line 3, characters 33-34:
|
||||
3 | [ "echo" "a" ] { foo:version < (foo = bar) }
|
||||
^
|
||||
Error: unable to parse opam file
|
||||
Parse error
|
||||
[1]
|
||||
|
||||
Package with package conjunction and string selections inside variable interpolations:
|
||||
$ mkpkg package-conjunction-and-string-selection <<EOF
|
||||
> build: [
|
||||
> [ "echo" "a %{installed}% b" ]
|
||||
> [ "echo" "c %{installed?x:y}% d" ]
|
||||
> [ "echo" "e %{foo:installed?x:y}% f" ]
|
||||
> [ "echo" "g %{foo+bar+_:installed?x:y}% h" ]
|
||||
> # The "enable" variable is syntactic sugar around "installed" in some (but not all) cases.
|
||||
> # Its intention appears to be for use with ./configure scripts that take --enable-<feature> or
|
||||
> # --disable-<feature> as arguments.
|
||||
> [ "echo" "--%{enable}%-feature" ]
|
||||
> [ "echo" "--%{_:enable}%-feature" ]
|
||||
> [ "echo" "--%{foo+bar:enable}%-feature" ]
|
||||
> [ "echo" "--%{foo+bar:enable?x:y}%-feature" ]
|
||||
> ]
|
||||
> EOF
|
||||
|
||||
$ solve_project <<EOF
|
||||
> (lang dune 3.8)
|
||||
> (package (name x) (depends package-conjunction-and-string-selection))
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
- package-conjunction-and-string-selection.0.0.1
|
||||
Note that "enable" is not a true opam variable. Opam desugars occurrences of
|
||||
"pkg:enable" into "pkg:enable?enable:disable" but if the explicit package scope
|
||||
is omitted then it's treated like a regular variable. That explains why the
|
||||
opam syntax `"--%{enable}%-feature"` is converted to
|
||||
`--%{pkg-self:enable}-feature`. Also if the "enable" pseudo-variable is used
|
||||
with an explicit string conversion it is treated as a regular variable which
|
||||
explains why the opam syntax `"--%{foo+bar:enable?x:y}%-feature"` is converted
|
||||
to a dune if-statement that checks the "enable" variable (rather than the
|
||||
"installed" variable as in other cases).
|
||||
|
||||
It's probably an error for opam packages to use the "enable" in ways that opam
|
||||
doesn't desugar but these tests are included so we can check that behaviour is
|
||||
preserved between opam and dune.
|
||||
$ cat dune.lock/package-conjunction-and-string-selection.pkg
|
||||
(version 0.0.1)
|
||||
|
||||
(build
|
||||
(progn
|
||||
(run echo "a %{pkg-self:installed} b")
|
||||
(run
|
||||
echo
|
||||
(concat
|
||||
"c "
|
||||
(if
|
||||
(catch_undefined_var %{pkg-self:installed} false)
|
||||
x
|
||||
y)
|
||||
" d"))
|
||||
(run
|
||||
echo
|
||||
(concat
|
||||
"e "
|
||||
(if
|
||||
(catch_undefined_var %{pkg:foo:installed} false)
|
||||
x
|
||||
y)
|
||||
" f"))
|
||||
(run
|
||||
echo
|
||||
(concat
|
||||
"g "
|
||||
(if
|
||||
(catch_undefined_var
|
||||
(and %{pkg:foo:installed} %{pkg:bar:installed} %{pkg-self:installed})
|
||||
false)
|
||||
x
|
||||
y)
|
||||
" h"))
|
||||
(run echo --%{pkg-self:enable}-feature)
|
||||
(run
|
||||
echo
|
||||
(concat
|
||||
--
|
||||
(if
|
||||
(catch_undefined_var %{pkg-self:installed} false)
|
||||
enable
|
||||
disable)
|
||||
-feature))
|
||||
(run
|
||||
echo
|
||||
(concat
|
||||
--
|
||||
(if
|
||||
(catch_undefined_var
|
||||
(and %{pkg:foo:installed} %{pkg:bar:installed})
|
||||
false)
|
||||
enable
|
||||
disable)
|
||||
-feature))
|
||||
(run
|
||||
echo
|
||||
(concat
|
||||
--
|
||||
(if
|
||||
(catch_undefined_var
|
||||
(and %{pkg:foo:enable} %{pkg:bar:enable})
|
||||
false)
|
||||
x
|
||||
y)
|
||||
-feature))))
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
Test the error message when curl is needed but not installed.
|
||||
|
||||
$ . ./helpers.sh
|
||||
$ make_lockdir
|
||||
|
||||
$ makepkg() {
|
||||
> make_lockpkg $1 <<EOF
|
||||
> (source
|
||||
> (fetch
|
||||
> (url "http://0.0.0.0:8000")))
|
||||
> (version dev)
|
||||
> EOF
|
||||
> }
|
||||
|
||||
$ makepkg foo
|
||||
|
||||
Build the package in an environment without curl.
|
||||
$ PATH=$(dirname $(which dune)) build_pkg foo
|
||||
File "dune.lock/foo.pkg", line 3, characters 7-28:
|
||||
3 | (url "http://0.0.0.0:8000")))
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
Error: The program "curl" does not appear to be installed. Dune uses curl to
|
||||
download packages. Dune requires that the "curl" executable be located in one
|
||||
of the directories listed in the PATH variable.
|
||||
Hint: Install curl with your system package manager.
|
||||
[1]
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
Some environment variables are automatically exported by packages:
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ make_lockdir
|
||||
$ echo "(version 0.0.1)" > dune.lock/test.pkg
|
||||
$ cat >dune.lock/usetest.pkg <<'EOF'
|
||||
> (version 0.0.1)
|
||||
> (depends test)
|
||||
> (build
|
||||
> (system "\| echo MANPATH=$MANPATH
|
||||
> "\| echo OCAMLPATH=$OCAMLPATH
|
||||
> "\| echo CAML_LD_LIBRARY_PATH=$CAML_LD_LIBRARY_PATH
|
||||
> "\| echo OCAMLTOP_INCLUDE_PATH=$OCAMLTOP_INCLUDE_PATH
|
||||
> "\| echo PATH=$PATH
|
||||
> ))
|
||||
> EOF
|
||||
|
||||
$ mkdir .bin
|
||||
$ ln -s $(which ocamlc) .bin/ocamlc
|
||||
$ ln -s $(which sh) .bin/sh
|
||||
$ dune=$(which dune)
|
||||
$ MANPATH="" OCAMLPATH="" CAML_LD_LIBRARY_PATH="" OCAMLTOP_INCLUDE_PATH="" PATH="$PWD/.bin" build_pkg usetest
|
||||
MANPATH=$TESTCASE_ROOT/_build/_private/default/.pkg/test/target/man
|
||||
OCAMLPATH=$TESTCASE_ROOT/_build/_private/default/.pkg/test/target/lib
|
||||
CAML_LD_LIBRARY_PATH=$TESTCASE_ROOT/_build/_private/default/.pkg/test/target/lib/stublibs
|
||||
OCAMLTOP_INCLUDE_PATH=$TESTCASE_ROOT/_build/_private/default/.pkg/test/target/lib/toplevel
|
||||
PATH=$TESTCASE_ROOT/_build/_private/default/.pkg/test/target/bin:$TESTCASE_ROOT/.bin
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
Modify the default branch of a source repo.
|
||||
|
||||
Once the branch is modified, dune should rebuild the package.
|
||||
|
||||
This bug is reported in #10063
|
||||
|
||||
$ . ../git-helpers.sh
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ src="_git_source"
|
||||
|
||||
$ mkdir $src && cd $src
|
||||
$ git init --quiet
|
||||
$ git checkout -b "branch1"
|
||||
Switched to a new branch 'branch1'
|
||||
$ echo "branch 1" > file
|
||||
$ git add -A
|
||||
$ git commit --quiet -m "branch 1"
|
||||
$ git checkout -b branch2
|
||||
Switched to a new branch 'branch2'
|
||||
$ echo "branch 2" > file
|
||||
$ git add -A
|
||||
$ git commit --quiet -m "branch 2"
|
||||
$ cd ..
|
||||
|
||||
$ make_lockdir
|
||||
$ make_lockpkg foo <<EOF
|
||||
> (source (fetch (url "git+file://$PWD/$src")))
|
||||
> (version 0.0.1)
|
||||
> (build (run cat file))
|
||||
> EOF
|
||||
|
||||
Build the package
|
||||
|
||||
$ build_pkg foo
|
||||
branch 2
|
||||
|
||||
Change the default branch
|
||||
|
||||
$ git -C $src checkout branch1
|
||||
Switched to branch 'branch1'
|
||||
|
||||
And now rebuild
|
||||
|
||||
$ build_pkg foo
|
||||
branch 1
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
Tests for the `dune describe pkg dependency-hash` command.
|
||||
|
||||
The case where there are no local packages:
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> EOF
|
||||
$ dune describe pkg dependency-hash
|
||||
Error: No non-local dependencies
|
||||
[1]
|
||||
|
||||
The case where there are local packages but no dependencies:
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package (name a))
|
||||
> (package (name b))
|
||||
> EOF
|
||||
$ dune describe pkg dependency-hash
|
||||
Error: No non-local dependencies
|
||||
[1]
|
||||
|
||||
The case where there are local packages with dependencies but no non-local
|
||||
dependencies:
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package (name a))
|
||||
> (package
|
||||
> (name b)
|
||||
> (depends a))
|
||||
> EOF
|
||||
$ dune describe pkg dependency-hash
|
||||
Error: No non-local dependencies
|
||||
[1]
|
||||
|
||||
A single package with a single non-local dependency:
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name a)
|
||||
> (depends
|
||||
> foo))
|
||||
> EOF
|
||||
$ dune describe pkg dependency-hash | tee hash1.txt
|
||||
36e640fbcda71963e7e2f689f6c96c3e
|
||||
|
||||
Adding another dependency causes the hash to change:
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name a)
|
||||
> (depends
|
||||
> foo
|
||||
> bar))
|
||||
> EOF
|
||||
$ dune describe pkg dependency-hash | tee hash2.txt
|
||||
b6404e14c268884f825aa1fb7d1b4ead
|
||||
$ diff hash1.txt hash2.txt
|
||||
1c1
|
||||
< 36e640fbcda71963e7e2f689f6c96c3e
|
||||
---
|
||||
> b6404e14c268884f825aa1fb7d1b4ead
|
||||
[1]
|
||||
|
||||
Adding a new local package which depends on one of the existing dependencies
|
||||
changes the hash:
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name a)
|
||||
> (depends
|
||||
> foo
|
||||
> bar))
|
||||
> (package
|
||||
> (name b)
|
||||
> (depends
|
||||
> foo))
|
||||
> EOF
|
||||
$ dune describe pkg dependency-hash | tee hash3.txt
|
||||
fa35416284004d71ff802a4c582f8797
|
||||
$ diff hash2.txt hash3.txt
|
||||
1c1
|
||||
< b6404e14c268884f825aa1fb7d1b4ead
|
||||
---
|
||||
> fa35416284004d71ff802a4c582f8797
|
||||
[1]
|
||||
|
||||
Adding a constraint to one of the dependencies causes the hash to change:
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name a)
|
||||
> (depends
|
||||
> foo
|
||||
> bar))
|
||||
> (package
|
||||
> (name b)
|
||||
> (depends
|
||||
> (foo (and :with-test (> 0.1)))))
|
||||
> EOF
|
||||
$ dune describe pkg dependency-hash | tee hash4.txt
|
||||
fdf713b190b56d52d8cdbdd72a382654
|
||||
$ diff hash3.txt hash4.txt
|
||||
1c1
|
||||
< fa35416284004d71ff802a4c582f8797
|
||||
---
|
||||
> fdf713b190b56d52d8cdbdd72a382654
|
||||
[1]
|
||||
|
||||
Adding another local package with the same dependency and constraint changes
|
||||
the hash:
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name a)
|
||||
> (depends
|
||||
> foo
|
||||
> bar))
|
||||
> (package
|
||||
> (name b)
|
||||
> (depends
|
||||
> (foo (and :with-test (> 0.1)))))
|
||||
> (package
|
||||
> (name c)
|
||||
> (depends
|
||||
> (foo (and :with-test (> 0.1)))))
|
||||
> EOF
|
||||
$ dune describe pkg dependency-hash | tee hash5.txt
|
||||
38fa247158bdf36939ec8b10b3205508
|
||||
$ diff hash4.txt hash5.txt
|
||||
1c1
|
||||
< fdf713b190b56d52d8cdbdd72a382654
|
||||
---
|
||||
> 38fa247158bdf36939ec8b10b3205508
|
||||
[1]
|
||||
|
||||
Make sure that the hash changes when the formula changes from a conjunction to
|
||||
a disjunction, thus changing the solution:
|
||||
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> EOF
|
||||
$ cat > local.opam <<EOF
|
||||
> opam-version: "2.0"
|
||||
> depends: [ "a" "b" ]
|
||||
> EOF
|
||||
$ dune describe pkg dependency-hash | tee hash-a-b.txt
|
||||
d18946fdd9833ae312d309f654f11c1b
|
||||
$ cat > local.opam <<EOF
|
||||
> opam-version: "2.0"
|
||||
> depends: [ "a" | "b" ]
|
||||
> EOF
|
||||
$ dune describe pkg dependency-hash | tee hash-a-or-b.txt
|
||||
5b2db8d296a969fbd80033f70919b2ec
|
||||
$ diff hash-a-and-b.txt hash-a-or-b.txt
|
||||
diff: hash-a-and-b.txt: No such file or directory
|
||||
[2]
|
||||
|
||||
The formula also changes if the dependencies being picked end up being the same
|
||||
("a" and "b") but the formula changed by including another dependency:
|
||||
|
||||
$ cat > local.opam <<EOF
|
||||
> opam-version: "2.0"
|
||||
> depends: [ "a" & ("b" | "c") ]
|
||||
> EOF
|
||||
$ dune describe pkg dependency-hash | tee hash-a-b-or-c.txt
|
||||
b704ac23e0d16a5e7a1b10aa6a8cbe0e
|
||||
$ diff hash-a-b.txt hash-a-b-or-c.txt
|
||||
1c1
|
||||
< d18946fdd9833ae312d309f654f11c1b
|
||||
---
|
||||
> b704ac23e0d16a5e7a1b10aa6a8cbe0e
|
||||
[1]
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
A package that installs itself into the ocaml stdlib should work.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ mkdir nondune
|
||||
$ cd nondune
|
||||
$ cat > nondune.ml <<EOF
|
||||
> let main () = print_endline "Nondune"
|
||||
> let () = main ()
|
||||
> EOF
|
||||
$ ocamlc -c nondune.ml
|
||||
$ ocamlc -o nondune.cma -a nondune.cmo
|
||||
$ cat > nondune.install <<EOF
|
||||
> lib_root: [
|
||||
> "nondune.cma" {"ocaml/nondune.cma"}
|
||||
> "nondune.cmi" {"ocaml/nondune.cmi"}
|
||||
> ]
|
||||
> lib: [
|
||||
> "META" {"META"}
|
||||
> ]
|
||||
> EOF
|
||||
$ cat > META <<EOF
|
||||
> directory = "^"
|
||||
> archive(byte) = "nondune.cma"
|
||||
> EOF
|
||||
$ cat > nondune.opam <<EOF
|
||||
> opam-version: "2.0"
|
||||
> build: [
|
||||
> [true]
|
||||
> ]
|
||||
> EOF
|
||||
$ cd ..
|
||||
|
||||
With this project set up, lets depend on it.
|
||||
|
||||
$ mkdir foo
|
||||
$ cd foo
|
||||
$ mkrepo
|
||||
$ solve_project <<EOF
|
||||
> (lang dune 3.15)
|
||||
> (pin
|
||||
> (url "file://$PWD/../nondune")
|
||||
> (package (name nondune)))
|
||||
> (package
|
||||
> (name foo)
|
||||
> (depends nondune))
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
- nondune.dev
|
||||
$ cat > dune <<EOF
|
||||
> (executable
|
||||
> (name foo)
|
||||
> (modules foo)
|
||||
> (libraries nondune)
|
||||
> (modes byte))
|
||||
> EOF
|
||||
$ cat > foo.ml <<EOF
|
||||
> let () = Nondune.main ()
|
||||
> EOF
|
||||
$ dune exec ./foo.exe 2>&1 | grep -o "Unbound module Nondune"
|
||||
Unbound module Nondune
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
When a package fails to build, dune will print opam depexts warning.
|
||||
|
||||
$ . ../helpers.sh
|
||||
$ mkrepo
|
||||
$ add_mock_repo_if_needed
|
||||
|
||||
Make a library that would fail when building it:
|
||||
$ mkdir foo
|
||||
$ cat > foo/dune-project <<EOF
|
||||
> EOF
|
||||
$ tar cf foo.tar foo
|
||||
$ rm -rf foo
|
||||
|
||||
Make a project that uses the foo library:
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.13)
|
||||
> (package
|
||||
> (name bar)
|
||||
> (depends foo))
|
||||
> EOF
|
||||
$ cat > dune <<EOF
|
||||
> (executable
|
||||
> (public_name bar)
|
||||
> (libraries foo))
|
||||
> EOF
|
||||
|
||||
Make dune.lock files with known program "dune".
|
||||
$ make_lockdir
|
||||
$ cat > dune.lock/foo.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (build
|
||||
> (run dune build))
|
||||
> (depexts unzip gnupg)
|
||||
> (source
|
||||
> (fetch
|
||||
> (url file://$PWD/foo.tar)
|
||||
> (checksum md5=$(md5sum foo.tar | cut -f1 -d' '))))
|
||||
> EOF
|
||||
|
||||
Build the project, when it fails building 'foo' package, it shows the depexts
|
||||
error message.
|
||||
$ dune build
|
||||
File "dune.lock/foo.pkg", line 3, characters 6-10:
|
||||
3 | (run dune build))
|
||||
^^^^
|
||||
Error: Logs for package foo
|
||||
File "dune-project", line 1, characters 0-0:
|
||||
Error: Invalid first line, expected: (lang <lang> <version>)
|
||||
|
||||
Hint: You may want to verify the following depexts are installed:
|
||||
- gnupg
|
||||
- unzip
|
||||
[1]
|
||||
|
||||
Make dune.lock files with unknown program and unknown package.
|
||||
$ make_lockdir
|
||||
$ cat > dune.lock/foo.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (build
|
||||
> (run unknown-program))
|
||||
> (depexts unknown-package)
|
||||
> (source
|
||||
> (fetch
|
||||
> (url file://$PWD/foo.tar)
|
||||
> (checksum md5=$(md5sum foo.tar | cut -f1 -d' '))))
|
||||
> EOF
|
||||
|
||||
Running the same build. It is supposed to show the depexts message at the end,
|
||||
when the program is not found.
|
||||
$ dune build
|
||||
File "dune.lock/foo.pkg", line 3, characters 6-21:
|
||||
3 | (run unknown-program))
|
||||
^^^^^^^^^^^^^^^
|
||||
Error: Program unknown-program not found in the tree or in PATH
|
||||
(context: default)
|
||||
Hint: You may want to verify the following depexts are installed:
|
||||
- unknown-package
|
||||
[1]
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
Show that the depexts that a project has can be printed.
|
||||
|
||||
$ . ../helpers.sh
|
||||
$ mkrepo
|
||||
|
||||
Make a project:
|
||||
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.13)
|
||||
> EOF
|
||||
|
||||
Create a lockdir with a package that features some depexts.
|
||||
|
||||
$ make_lockdir
|
||||
$ cat > dune.lock/foo.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (depexts unzip gnupg)
|
||||
> EOF
|
||||
|
||||
Printing the depexts should show all the depexts that the project has:
|
||||
|
||||
$ dune show depexts
|
||||
gnupg
|
||||
unzip
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
Solving would add opam 'depext' field to lock directory packages
|
||||
|
||||
$ . ../helpers.sh
|
||||
$ mkrepo
|
||||
$ add_mock_repo_if_needed
|
||||
|
||||
Make a package for the library with depexts:
|
||||
$ mkpkg foo <<EOF
|
||||
> depexts: [["unzip" "gnupg"]]
|
||||
> EOF
|
||||
|
||||
Make a project that uses the foo library:
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.13)
|
||||
> (package
|
||||
> (name bar)
|
||||
> (depends foo))
|
||||
> EOF
|
||||
|
||||
locking would add the opam 'depext' field to foo.pkg
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- foo.0.0.1
|
||||
$ cat dune.lock/foo.pkg
|
||||
(version 0.0.1)
|
||||
|
||||
(depexts unzip gnupg)
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
Solving with an unknown variable on depexts:
|
||||
|
||||
$ . ../helpers.sh
|
||||
$ mkrepo
|
||||
$ add_mock_repo_if_needed
|
||||
|
||||
The "foobar" variable is not defined:
|
||||
$ mkpkg foo <<EOF
|
||||
> depexts: [[ "unzip" ] {foobar}]
|
||||
> EOF
|
||||
|
||||
Make a project that uses the foo library:
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.13)
|
||||
> (package
|
||||
> (name bar)
|
||||
> (depends foo))
|
||||
> EOF
|
||||
|
||||
Locking should succeed and not include the "unzip" package
|
||||
$ dune pkg lock 2>&1 | head -n 1
|
||||
Solution for dune.lock:
|
||||
|
||||
$ [ -e dune.lock/foo.pkg ] && cat dune.lock/foo.pkg
|
||||
(version 0.0.1)
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
Test that available optional dependencies of a package are added to the
|
||||
"depends" field of that package's lockfile.
|
||||
|
||||
$ . ../helpers.sh
|
||||
$ mkrepo
|
||||
|
||||
$ mkpkg a
|
||||
$ mkpkg b
|
||||
|
||||
Make a package which has a regular dependency and an optional dependency.
|
||||
$ mkpkg foo <<EOF
|
||||
> depends: [ "a" ]
|
||||
> depopts: [ "b" ]
|
||||
> EOF
|
||||
|
||||
The optional dependency on "b" is not included in foo's dependencies because
|
||||
"b" is not part of the package solution:
|
||||
$ solve foo
|
||||
Solution for dune.lock:
|
||||
- a.0.0.1
|
||||
- foo.0.0.1
|
||||
$ cat dune.lock/foo.pkg
|
||||
(version 0.0.1)
|
||||
|
||||
(depends a)
|
||||
|
||||
Another package which has a regular dependency on "b":
|
||||
$ mkpkg bar <<EOF
|
||||
> depends: [ "b" ]
|
||||
> EOF
|
||||
|
||||
Solve again, this time depending on both "foo" and "bar". Now "b" is among
|
||||
the dependencies of "foo", since "b" is part of the package solution:
|
||||
$ solve foo bar
|
||||
Solution for dune.lock:
|
||||
- a.0.0.1
|
||||
- b.0.0.1
|
||||
- bar.0.0.1
|
||||
- foo.0.0.1
|
||||
$ cat dune.lock/foo.pkg
|
||||
(version 0.0.1)
|
||||
|
||||
(depends a b)
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
This tests that depopts are considered optional by the solver.
|
||||
|
||||
$ . ../helpers.sh
|
||||
$ mkrepo
|
||||
$ mkpkg foo
|
||||
$ mkpkg bar
|
||||
|
||||
We create a package that depends on foo and has an optional dependency on bar
|
||||
but also a conflict with bar. This should ensure that bar is never selected by
|
||||
the solver.
|
||||
|
||||
$ solve_project << EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name x)
|
||||
> (depends foo)
|
||||
> (depopts bar)
|
||||
> (conflicts bar))
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
- foo.0.0.1
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
We test depopts with conflicting constraints to see which one the solver will
|
||||
prefer if any:
|
||||
|
||||
$ . ../helpers.sh
|
||||
$ mkpkg foo 1
|
||||
$ mkpkg foo 2
|
||||
|
||||
$ mkpkg bar <<'EOF'
|
||||
> depopts: [ "foo" {= "1"} ]
|
||||
> EOF
|
||||
|
||||
$ mkpkg baz <<'EOF'
|
||||
> depopts: [ "foo" {= "2"} ]
|
||||
> EOF
|
||||
|
||||
We don't currently support depopts so they are both omitted.
|
||||
|
||||
$ solve bar baz
|
||||
Solution for dune.lock:
|
||||
- bar.0.0.1
|
||||
- baz.0.0.1
|
||||
|
||||
It's possible to find a solution by satisfying one (but not both) depopts.
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
We test how the solver chooses a solution for depopts with constraints.
|
||||
|
||||
$ . ../helpers.sh
|
||||
$ mkrepo
|
||||
|
||||
We create a package "foo" that is the dependency of two packages "optional" and
|
||||
"bar".
|
||||
|
||||
$ mkpkg foo 1
|
||||
|
||||
The package "optional" has a constraint on a particular version of "foo".
|
||||
|
||||
$ mkpkg optional <<'EOF'
|
||||
> depends: [ "foo" {= "1"} ]
|
||||
> EOF
|
||||
|
||||
The package "bar" depends on "foo" and depends optionally on "optional".
|
||||
|
||||
$ mkpkg bar <<'EOF'
|
||||
> depends: [ "foo" ]
|
||||
> depopts: [ "optional" ]
|
||||
> EOF
|
||||
|
||||
Here the solver could pick "bar" and "foo", and perphaps pick "optional",
|
||||
however this is not required.
|
||||
|
||||
$ solve bar
|
||||
Solution for dune.lock:
|
||||
- bar.0.0.1
|
||||
- foo.1
|
||||
|
||||
Since the version of "foo" is constrained by "optional", "optional" should be
|
||||
excluded from the build plan if the latest version of "foo" is picked.
|
||||
|
||||
$ mkpkg foo 2
|
||||
$ solve bar
|
||||
Solution for dune.lock:
|
||||
- bar.0.0.1
|
||||
- foo.2
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
Selecting depopts
|
||||
|
||||
$ . ../helpers.sh
|
||||
$ mkrepo
|
||||
$ mkpkg foo
|
||||
$ mkpkg bar
|
||||
|
||||
$ solve_project << EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name x)
|
||||
> (depends foo)
|
||||
> (depopts bar))
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
- foo.0.0.1
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
Reproduce github issue #11058
|
||||
|
||||
Handling of more than one depopt:
|
||||
|
||||
$ . ../helpers.sh
|
||||
|
||||
$ mkpkg a
|
||||
$ mkpkg b
|
||||
$ mkpkg c
|
||||
$ mkpkg d
|
||||
$ mkpkg e
|
||||
$ mkpkg f
|
||||
|
||||
$ runtest() {
|
||||
> mkpkg bar <<'EOF'
|
||||
> depopts: [ "a" "b" "c" ]
|
||||
> EOF
|
||||
> solve bar
|
||||
> }
|
||||
|
||||
$ runtest <<'EOF'
|
||||
> depopts: [ "a" "b" "c" ]
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
- bar.0.0.1
|
||||
|
||||
$ runtest <<'EOF'
|
||||
> depopts: [ "a" "b" "c" "d" ]
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
- bar.0.0.1
|
||||
|
||||
$ runtest <<'EOF'
|
||||
> depopts: [ ("a" | "b") "c" "d" ]
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
- bar.0.0.1
|
||||
|
||||
$ runtest <<'EOF'
|
||||
> depopts: [ (("e" | "a") | ("d" | "f")) "b" "c" ]
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
- bar.0.0.1
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
Reproduce the bug in #11698
|
||||
|
||||
$ . ../helpers.sh
|
||||
|
||||
$ mkrepo
|
||||
$ add_mock_repo_if_needed
|
||||
|
||||
$ mkpkg fmt
|
||||
$ mkpkg semver
|
||||
|
||||
$ mkdir _dep
|
||||
$ cat >_dep/dune-project <<EOF
|
||||
> (lang dune 3.18)
|
||||
> (package
|
||||
> (name dep)
|
||||
> (depopts fmt semver))
|
||||
> EOF
|
||||
|
||||
$ solve_project <<EOF
|
||||
> (lang dune 3.18)
|
||||
> (pin
|
||||
> (url "file://$PWD/_dep")
|
||||
> (package
|
||||
> (name dep)
|
||||
> (version 1.0.0)))
|
||||
> (package
|
||||
> (name x)
|
||||
> (depends dep))
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
- dep.1.0.0
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
We test how opam files with depopts fields are translated into dune.lock files:
|
||||
|
||||
$ . ../helpers.sh
|
||||
$ mkrepo
|
||||
|
||||
Make a package with a depopts field
|
||||
$ mkpkg with-depopts <<'EOF'
|
||||
> depopts: [ "foo" ]
|
||||
> EOF
|
||||
$ mkpkg foo
|
||||
|
||||
$ solve with-depopts
|
||||
Solution for dune.lock:
|
||||
- with-depopts.0.0.1
|
||||
|
||||
When depopts are supported and selected, the above lock should change and we
|
||||
should also be able to see a deps field in the lock file:
|
||||
|
||||
$ cat dune.lock/with-depopts.pkg
|
||||
(version 0.0.1)
|
||||
|
||||
We should also be able to validate the lock directory:
|
||||
|
||||
$ dune pkg validate-lockdir
|
||||
|
||||
Depopts should not be selected if they conflict with other constraints:
|
||||
|
||||
$ mkpkg no-foo <<'EOF'
|
||||
> depends: [ "with-depopts" ]
|
||||
> conflicts: [ "foo" ]
|
||||
> EOF
|
||||
|
||||
$ solve no-foo
|
||||
Solution for dune.lock:
|
||||
- no-foo.0.0.1
|
||||
- with-depopts.0.0.1
|
||||
|
||||
$ dune pkg validate-lockdir
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
Demonstrate how depopts can be forced in the workspace
|
||||
|
||||
$ . ../helpers.sh
|
||||
|
||||
$ mkrepo
|
||||
|
||||
$ mkpkg foo
|
||||
$ mkpkg bar
|
||||
$ mkpkg baz
|
||||
|
||||
$ solve_project <<EOF
|
||||
> (lang dune 3.18)
|
||||
> (package
|
||||
> (name x)
|
||||
> (depopts foo bar))
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
(no dependencies to lock)
|
||||
|
||||
Select just foo
|
||||
|
||||
$ cat >dune-workspace <<EOF
|
||||
> (lang dune 3.10)
|
||||
> (lock_dir
|
||||
> (depopts foo)
|
||||
> (repositories mock))
|
||||
> (repository
|
||||
> (name mock)
|
||||
> (url "file://$PWD/mock-opam-repository"))
|
||||
> EOF
|
||||
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- foo.0.0.1
|
||||
|
||||
Select both foo and bar
|
||||
|
||||
$ cat >dune-workspace <<EOF
|
||||
> (lang dune 3.10)
|
||||
> (lock_dir
|
||||
> (depopts foo bar)
|
||||
> (repositories mock))
|
||||
> (repository
|
||||
> (name mock)
|
||||
> (url "file://$PWD/mock-opam-repository"))
|
||||
> EOF
|
||||
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- bar.0.0.1
|
||||
- foo.0.0.1
|
||||
|
||||
Select a package that is not listed as depopt
|
||||
|
||||
$ cat >dune-workspace <<EOF
|
||||
> (lang dune 3.10)
|
||||
> (lock_dir
|
||||
> (depopts baz)
|
||||
> (repositories mock))
|
||||
> (repository
|
||||
> (name mock)
|
||||
> (url "file://$PWD/mock-opam-repository"))
|
||||
> EOF
|
||||
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
(no dependencies to lock)
|
||||
|
||||
|
||||
Select garbage
|
||||
|
||||
$ cat >dune-workspace <<EOF
|
||||
> (lang dune 3.10)
|
||||
> (lock_dir
|
||||
> (depopts z)
|
||||
> (repositories mock))
|
||||
> (repository
|
||||
> (name mock)
|
||||
> (url "file://$PWD/mock-opam-repository"))
|
||||
> EOF
|
||||
|
||||
$ dune pkg lock
|
||||
Error: Unable to solve dependencies for the following lock directories:
|
||||
Lock directory dune.lock:
|
||||
Couldn't solve the package dependency formula.
|
||||
The following packages couldn't be found: z
|
||||
[1]
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
|
||||
Testing the output of the dune describe pkg lock command.
|
||||
|
||||
First we setup a repo.
|
||||
$ mkpkg A 1.2.0
|
||||
> mkpkg B 2.1+rc1
|
||||
> mkpkg C 81.0.4044.138 <<EOF
|
||||
> depends: [ "D" "E" ]
|
||||
> EOF
|
||||
> mkpkg D 0.4.0.beta1
|
||||
> mkpkg E 3.0~alpha1
|
||||
|
||||
$ cat > dune-workspace <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (context
|
||||
> (default))
|
||||
> (context
|
||||
> (default
|
||||
> (name "foo")
|
||||
> (lock_dir foo.lock)))
|
||||
> (lock_dir
|
||||
> (repositories mock))
|
||||
> (lock_dir
|
||||
> (path foo.lock)
|
||||
> (repositories mock))
|
||||
> (repository
|
||||
> (name mock)
|
||||
> (url "file://$(pwd)/mock-opam-repository"))
|
||||
> EOF
|
||||
|
||||
Here is the output of solving for multiple contexts:
|
||||
$ solve_project --all <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name x)
|
||||
> (depends A B C))
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
- A.1.2.0
|
||||
- B.2.1+rc1
|
||||
- C.81.0.4044.138
|
||||
- D.0.4.0.beta1
|
||||
- E.3.0~alpha1
|
||||
Solution for foo.lock:
|
||||
- A.1.2.0
|
||||
- B.2.1+rc1
|
||||
- C.81.0.4044.138
|
||||
- D.0.4.0.beta1
|
||||
- E.3.0~alpha1
|
||||
Here is the output of dune describe pkg lock:
|
||||
$ dune describe pkg lock
|
||||
Contents of dune.lock:
|
||||
- A.1.2.0
|
||||
- B.2.1+rc1
|
||||
- C.81.0.4044.138
|
||||
- D.0.4.0.beta1
|
||||
- E.3.0~alpha1
|
||||
|
||||
The names of the lockfiles can also be provided:
|
||||
$ dune describe pkg lock dune.lock foo.lock
|
||||
Contents of dune.lock:
|
||||
- A.1.2.0
|
||||
- B.2.1+rc1
|
||||
- C.81.0.4044.138
|
||||
- D.0.4.0.beta1
|
||||
- E.3.0~alpha1
|
||||
Contents of foo.lock:
|
||||
- A.1.2.0
|
||||
- B.2.1+rc1
|
||||
- C.81.0.4044.138
|
||||
- D.0.4.0.beta1
|
||||
- E.3.0~alpha1
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
Exercise printing the help messages for dev tools commands.
|
||||
|
||||
Disable the pagers, as the command line parser might use a pager from the users
|
||||
system which will reformat the output if not specifically requesting `plain`
|
||||
output.
|
||||
|
||||
$ export PAGER=false
|
||||
$ export MANPAGER=false
|
||||
|
||||
Output the help text:
|
||||
|
||||
$ dune tools exec --help=plain
|
||||
NAME
|
||||
dune-tools-exec - Command group for running wrapped tools.
|
||||
|
||||
SYNOPSIS
|
||||
dune tools exec COMMAND …
|
||||
|
||||
COMMANDS
|
||||
ocamlearlybird [OPTION]… [ARGS]…
|
||||
Wrapper for running ocamlearlybird intended to be run
|
||||
automatically by a text editor. All positional arguments will be
|
||||
passed to the ocamlearlybird executable (pass flags to
|
||||
ocamlearlybird after the '--' argument, such as 'dune tools exec
|
||||
ocamlearlybird -- --help').
|
||||
|
||||
ocamlformat [OPTION]… [ARGS]…
|
||||
Wrapper for running ocamlformat intended to be run automatically
|
||||
by a text editor. All positional arguments will be passed to the
|
||||
ocamlformat executable (pass flags to ocamlformat after the '--'
|
||||
argument, such as 'dune tools exec ocamlformat -- --help').
|
||||
|
||||
ocamllsp [OPTION]… [ARGS]…
|
||||
Wrapper for running ocamllsp intended to be run automatically by a
|
||||
text editor. All positional arguments will be passed to the
|
||||
ocamllsp executable (pass flags to ocamllsp after the '--'
|
||||
argument, such as 'dune tools exec ocamllsp -- --help').
|
||||
|
||||
COMMON OPTIONS
|
||||
--help[=FMT] (default=auto)
|
||||
Show this help in format FMT. The value FMT must be one of auto,
|
||||
pager, groff or plain. With auto, the format is pager or plain
|
||||
whenever the TERM env var is dumb or undefined.
|
||||
|
||||
--version
|
||||
Show version information.
|
||||
|
||||
EXIT STATUS
|
||||
dune tools exec exits with:
|
||||
|
||||
0 on success.
|
||||
|
||||
1 if an error happened.
|
||||
|
||||
130 if it was interrupted by a signal.
|
||||
|
||||
SEE ALSO
|
||||
dune(1)
|
||||
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
Clarify the behavior when the `dune` in PATH is not the one used to start the build.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ make_test_package() {
|
||||
> mkdir tmp
|
||||
> cd tmp
|
||||
> cat > dune-project <<EOF
|
||||
> (lang dune 3.13)
|
||||
> (package
|
||||
> (name $1)
|
||||
> (allow_empty))
|
||||
> EOF
|
||||
> cd ..
|
||||
> tar cf $1.tar tmp
|
||||
> rm -rf tmp
|
||||
> }
|
||||
|
||||
$ make_test_package foo
|
||||
$ make_test_package bar
|
||||
|
||||
Make a project that depends on the test packages:
|
||||
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.13)
|
||||
> (package
|
||||
> (name x)
|
||||
> (allow_empty)
|
||||
> (depends foo bar))
|
||||
> EOF
|
||||
|
||||
$ cat > dune <<EOF
|
||||
> (data_only_dirs bin)
|
||||
> EOF
|
||||
|
||||
Make lockfiles for the packages.
|
||||
$ make_lockdir
|
||||
$ make_lockpkg foo <<EOF
|
||||
> (version 0.0.1)
|
||||
>
|
||||
> (build
|
||||
> (run dune build -p %{pkg-self:name} @install))
|
||||
>
|
||||
> (source
|
||||
> (fetch
|
||||
> (url $PWD/foo.tar)))
|
||||
>
|
||||
> (dev)
|
||||
> EOF
|
||||
|
||||
$ make_lockpkg bar <<EOF
|
||||
> (version 0.0.1)
|
||||
>
|
||||
> (build
|
||||
> ; Exercise that the dune exe can be located when it's launched by a subprocess.
|
||||
> (run sh -c "dune build -p %{pkg-self:name} @install"))
|
||||
>
|
||||
> (source
|
||||
> (fetch
|
||||
> (url $PWD/bar.tar)))
|
||||
>
|
||||
> (dev)
|
||||
> EOF
|
||||
|
||||
Test that the project can be built normally.
|
||||
$ build_pkg foo
|
||||
|
||||
Make a fake dune exe:
|
||||
$ mkdir bin
|
||||
$ cat > bin/dune <<EOF
|
||||
> #!/bin/sh
|
||||
> echo "Fake dune! (args: \$@)"
|
||||
> EOF
|
||||
$ chmod a+x bin/dune
|
||||
|
||||
$ dune clean
|
||||
Try building in an environment where `dune` refers to the fake dune.
|
||||
$ DUNE=$(which dune) # otherwise we would start by running the wrong dune
|
||||
$ PATH=$PWD/bin:$PATH $DUNE build $pkg_root/foo/target/
|
||||
Fake dune! (args: build -p foo @install)
|
||||
$ PATH=$PWD/bin:$PATH $DUNE build $pkg_root/bar/target/
|
||||
Fake dune! (args: build -p bar @install)
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
(cram
|
||||
(alias pkg)
|
||||
(applies_to :whole_subtree))
|
||||
|
||||
(env
|
||||
(_
|
||||
(env-vars
|
||||
(DUNE_DEBUG_PACKAGE_LOGS 1))))
|
||||
|
||||
(cram
|
||||
(deps helpers.sh %{bin:git} ../git-helpers.sh)
|
||||
(applies_to :whole_subtree))
|
||||
|
||||
(cram
|
||||
(deps %{bin:patch})
|
||||
(applies_to patch opam-package-with-patch extra-sources))
|
||||
|
||||
(cram
|
||||
(applies_to rev-store-lock-linux)
|
||||
(enabled_if
|
||||
(= %{system} linux))
|
||||
(deps %{bin:strace}))
|
||||
|
||||
(cram
|
||||
(deps %{bin:awk} %{bin:cmp})
|
||||
(applies_to git-repo))
|
||||
|
||||
(cram
|
||||
(deps %{bin:make})
|
||||
(applies_to make))
|
||||
|
||||
(cram
|
||||
(deps %{bin:which})
|
||||
(applies_to pkg-deps))
|
||||
|
||||
(cram
|
||||
(deps %{bin:curl})
|
||||
(applies_to
|
||||
unavailable-source-package
|
||||
compute-checksums-when-missing
|
||||
e2e
|
||||
ocamlformat-dev-tool
|
||||
source-caching
|
||||
tarball
|
||||
pin-depends
|
||||
extra-sources
|
||||
broken-symlink-in-dependency))
|
||||
|
||||
(cram
|
||||
(deps %{bin:md5sum})
|
||||
(applies_to
|
||||
source-caching
|
||||
extra-sources
|
||||
ocamlformat-dev-tool
|
||||
dev-tool-conflict-test
|
||||
broken-symlink-in-dependency))
|
||||
|
||||
(cram
|
||||
(deps %{bin:tar})
|
||||
(applies_to
|
||||
source-caching
|
||||
tarball
|
||||
pin-depends
|
||||
extra-sources
|
||||
pkg-extract-fail
|
||||
broken-symlink-in-dependency))
|
||||
|
||||
(cram
|
||||
(deps %{bin:ocaml_index})
|
||||
(applies_to gh10985))
|
||||
|
||||
(cram
|
||||
(deps %{bin:unzip})
|
||||
(applies_to pkg-extract-fail))
|
||||
|
||||
;; disabled for flakiness
|
||||
|
||||
(cram
|
||||
(enabled_if false)
|
||||
(applies_to gh10959))
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
We configure the same lock directory twice:
|
||||
|
||||
$ cat >dune-workspace <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (lock_dir (path foo))
|
||||
> (lock_dir (path foo))
|
||||
> EOF
|
||||
|
||||
$ dune build
|
||||
|
||||
Another way to define a duplicate is by omitting the path. Since it defaults to
|
||||
dune.lock:
|
||||
|
||||
$ cat >dune-workspace <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (lock_dir)
|
||||
> (lock_dir (path dune.lock))
|
||||
> EOF
|
||||
|
||||
$ dune build
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
A workspace with a package that exists in the lock file and in the workspace
|
||||
shouldn't be allowed (for now)
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> EOF
|
||||
|
||||
$ cat > mypkg.opam <<EOF
|
||||
> opam-version: "2.0"
|
||||
> EOF
|
||||
$ mkdir dune.lock
|
||||
$ cat >dune.lock/lock.dune <<EOF
|
||||
> (lang package 0.1)
|
||||
> EOF
|
||||
$ touch dune.lock/mypkg.lock
|
||||
|
||||
$ dune build
|
||||
|
||||
It should also fail when we define the package only in the dune-project file:
|
||||
|
||||
$ rm mypkg.opam
|
||||
$ cat >>dune-project <<EOF
|
||||
> (package
|
||||
> (allow_empty)
|
||||
> (name mypkg))
|
||||
> EOF
|
||||
|
||||
$ dune build
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
Duplicate repository definition in the same workspace file:
|
||||
|
||||
$ cat >dune-workspace <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (repository
|
||||
> (name foo)
|
||||
> (url "git+file//$PWD/foo"))
|
||||
> (repository
|
||||
> (name foo)
|
||||
> (url "git+file//$PWD/foo"))
|
||||
> EOF
|
||||
|
||||
$ dune pkg outdated 2>&1 | awk '/Internal error/,/Raised/'
|
||||
Internal error, please report upstream including the contents of _build/log.
|
||||
Description:
|
||||
("Map.of_list_exn", { key = "foo" })
|
||||
Raised at Stdune__Code_error.raise in file
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
Exercises end to end locking and building a simple project.
|
||||
|
||||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
$ add_mock_repo_if_needed
|
||||
|
||||
Make a library:
|
||||
$ mkdir foo
|
||||
$ cd foo
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.13)
|
||||
> (package (name foo))
|
||||
> EOF
|
||||
$ cat > foo.ml <<EOF
|
||||
> let foo = "Hello, World!"
|
||||
> EOF
|
||||
$ cat > dune <<EOF
|
||||
> (library
|
||||
> (public_name foo))
|
||||
> EOF
|
||||
$ cd ..
|
||||
$ tar cf foo.tar foo
|
||||
$ rm -rf foo
|
||||
|
||||
Configure our fake curl to serve the tarball
|
||||
|
||||
$ echo foo.tar >> fake-curls
|
||||
$ PORT=1
|
||||
|
||||
Make a package for the library:
|
||||
$ mkpkg foo <<EOF
|
||||
> build: [
|
||||
> ["dune" "subst"] {dev}
|
||||
> [
|
||||
> "dune"
|
||||
> "build"
|
||||
> "-p"
|
||||
> name
|
||||
> "-j"
|
||||
> jobs
|
||||
> "@install"
|
||||
> "@runtest" {with-test}
|
||||
> "@doc" {with-doc}
|
||||
> ]
|
||||
> ]
|
||||
> url {
|
||||
> src: "http://0.0.0.0:$PORT"
|
||||
> checksum: [
|
||||
> "md5=$(md5sum foo.tar | cut -f1 -d' ')"
|
||||
> ]
|
||||
> }
|
||||
> EOF
|
||||
|
||||
Make a project that uses the library:
|
||||
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.13)
|
||||
> (package
|
||||
> (name bar)
|
||||
> (depends foo))
|
||||
> EOF
|
||||
|
||||
$ cat > bar.ml <<EOF
|
||||
> let () = print_endline Foo.foo
|
||||
> EOF
|
||||
|
||||
$ cat > dune <<EOF
|
||||
> (executable
|
||||
> (public_name bar)
|
||||
> (libraries foo))
|
||||
> EOF
|
||||
|
||||
Lock, build, and run the executable in the project:
|
||||
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- foo.0.0.1
|
||||
$ dune exec bar
|
||||
Hello, World!
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
|
||||
A package with different linux and macos dependencies including a test-only
|
||||
dependency:
|
||||
$ mkpkg foo <<EOF
|
||||
> depends: [
|
||||
> "foo-linux" {os = "linux"}
|
||||
> "foo-macos" {os = "macos"}
|
||||
> "foo-macos-test-only" {os = "macos" & with-test}
|
||||
> ]
|
||||
> EOF
|
||||
$ mkpkg foo-linux <<EOF
|
||||
> available: os = "linux"
|
||||
> EOF
|
||||
$ mkpkg foo-linux-test-only <<EOF
|
||||
> available: os = "linux"
|
||||
> EOF
|
||||
$ mkpkg foo-macos <<EOF
|
||||
> available: os = "macos"
|
||||
> EOF
|
||||
|
||||
Create a workspace config that defines separate build contexts for macos and linux.
|
||||
$ cat >dune-workspace <<EOF
|
||||
> (lang dune 3.8)
|
||||
> (lock_dir
|
||||
> (path dune.no-os.lock)
|
||||
> (repositories mock)
|
||||
> (solver_env
|
||||
> (unset_variables os)))
|
||||
> (lock_dir
|
||||
> (path dune.linux.lock)
|
||||
> (repositories mock)
|
||||
> (solver_env
|
||||
> (os linux)))
|
||||
> (lock_dir
|
||||
> (path dune.macos.lock)
|
||||
> (repositories mock)
|
||||
> (solver_env
|
||||
> (os macos)))
|
||||
> (lock_dir
|
||||
> (path dune.lock)
|
||||
> (repositories mock))
|
||||
> (context
|
||||
> (default
|
||||
> (name linux)
|
||||
> (lock_dir dune.linux.lock)))
|
||||
> (context
|
||||
> (default
|
||||
> (name macos)
|
||||
> (lock_dir dune.macos.lock)))
|
||||
> (repository
|
||||
> (name mock)
|
||||
> (url "file://$(pwd)/mock-opam-repository"))
|
||||
> EOF
|
||||
|
||||
Now the os-specific dependencies are included on their respective systems.
|
||||
$ dune pkg lock --all
|
||||
Solution for dune.linux.lock:
|
||||
(no dependencies to lock)
|
||||
Solution for dune.lock:
|
||||
(no dependencies to lock)
|
||||
Solution for dune.macos.lock:
|
||||
(no dependencies to lock)
|
||||
Solution for dune.no-os.lock:
|
||||
(no dependencies to lock)
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
Test for packages with no source field but with extra_sources.
|
||||
|
||||
$ . ./helpers.sh
|
||||
$ make_lockdir
|
||||
|
||||
$ cat > dune.lock/foo.pkg <<EOF
|
||||
> (version 1)
|
||||
> (extra_sources
|
||||
> (foo.txt
|
||||
> (fetch
|
||||
> (url file://$PWD/foo.txt))))
|
||||
> EOF
|
||||
|
||||
$ touch foo.txt
|
||||
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.16)
|
||||
> (package
|
||||
> (allow_empty)
|
||||
> (name a)
|
||||
> (depends foo))
|
||||
> EOF
|
||||
|
||||
$ dune build
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
Packages can export environment variables
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ make_lockdir
|
||||
$ cat >dune.lock/test.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (exported_env
|
||||
> (= FOO bar)
|
||||
> (= BAR xxx)
|
||||
> (+= BAR yyy)
|
||||
> (:= BAR zzz))
|
||||
> EOF
|
||||
|
||||
$ cat >dune.lock/usetest.pkg <<'EOF'
|
||||
> (depends test)
|
||||
> (version 1.2.3)
|
||||
> (build
|
||||
> (progn
|
||||
> (system "\| echo FOO=$FOO
|
||||
> "\| echo BAR=$BAR
|
||||
> "\| echo OPAM_PACKAGE_NAME=$OPAM_PACKAGE_NAME
|
||||
> "\| echo OPAM_PACKAGE_VERSION=$OPAM_PACKAGE_VERSION
|
||||
> )
|
||||
> (run mkdir -p %{prefix})))
|
||||
> EOF
|
||||
|
||||
$ build_pkg usetest
|
||||
FOO=bar
|
||||
BAR=zzz:yyy:xxx
|
||||
OPAM_PACKAGE_NAME=usetest
|
||||
OPAM_PACKAGE_VERSION=1.2.3
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
A lock directory which does not exist in the source tree:
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ mkdir dune.lock project
|
||||
$ cat >dune.lock/foo.pkg <<EOF
|
||||
> (build (run echo foo))
|
||||
> (version 1.0.0)
|
||||
> EOF
|
||||
|
||||
$ cat >dune-workspace <<EOF
|
||||
> (lang dune 3.13)
|
||||
> (lock_dir (path $PWD/dune.lock))
|
||||
> EOF
|
||||
|
||||
$ build_pkg foo 2>&1 | awk '/Internal error/,/Raised/'
|
||||
Internal error, please report upstream including the contents of _build/log.
|
||||
Description:
|
||||
("Local.relative: received absolute path",
|
||||
{ t = "."
|
||||
; path =
|
||||
"$TESTCASE_ROOT/dune.lock"
|
||||
})
|
||||
Raised at Stdune__Code_error.raise in file
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
Test that can fetch the sources from an external dir
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ mkdir foo
|
||||
$ echo "y" > foo/x
|
||||
|
||||
$ make_lockdir
|
||||
$ cat >dune.lock/test.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (source (copy $PWD/foo))
|
||||
> (build
|
||||
> (progn
|
||||
> (run mkdir -p %{prefix}/bin)
|
||||
> (run cp x %{prefix}/bin/x)))
|
||||
> EOF
|
||||
|
||||
$ build_pkg test
|
||||
|
||||
$ show_pkg test
|
||||
|
||||
/source
|
||||
/source/x
|
||||
/target
|
||||
/target/bin
|
||||
/target/bin/x
|
||||
/target/cookie
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
Test for packages with an extra-source file with the same name as a
|
||||
file in the package's source.
|
||||
|
||||
$ . ./helpers.sh
|
||||
$ make_lockdir
|
||||
|
||||
$ cat > dune.lock/foo.pkg <<EOF
|
||||
> (version 1)
|
||||
> (source
|
||||
> (copy $PWD/foo-source))
|
||||
> (extra_sources
|
||||
> (foo.txt
|
||||
> (fetch
|
||||
> (url file://$PWD/foo.txt))))
|
||||
> EOF
|
||||
|
||||
$ mkdir -p foo-source
|
||||
$ echo "from source" > foo-source/foo.txt
|
||||
|
||||
$ echo "from extra source" > foo.txt
|
||||
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.16)
|
||||
> (package
|
||||
> (allow_empty)
|
||||
> (name a)
|
||||
> (depends foo))
|
||||
> EOF
|
||||
|
||||
$ build_pkg foo
|
||||
|
||||
Make sure that the package's source directory ends up with the version
|
||||
of foo.txt from extra_sources:
|
||||
$ cat _build/_private/default/.pkg/foo/source/foo.txt
|
||||
from extra source
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
Fetch from more than one source
|
||||
|
||||
$ . ../git-helpers.sh
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ make_lockdir
|
||||
$ mkdir foo
|
||||
$ cat >foo/bar <<EOF
|
||||
> this is bar
|
||||
> EOF
|
||||
|
||||
$ cat >baz <<EOF
|
||||
> this is baz
|
||||
> EOF
|
||||
|
||||
$ cat >dune.lock/test.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (source (copy $PWD/foo))
|
||||
> (extra_sources (mybaz (copy $PWD/baz)))
|
||||
> (build
|
||||
> (system "find . | sort -u"))
|
||||
> EOF
|
||||
|
||||
$ build_pkg test
|
||||
.
|
||||
./bar
|
||||
./mybaz
|
||||
|
||||
Make sure extra source patches are downloaded, checksum-verified and applied
|
||||
when building.
|
||||
|
||||
First we need a project that will have the patch applied:
|
||||
|
||||
$ mkdir needs-patch
|
||||
$ cd needs-patch
|
||||
$ git init --quiet
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.15)
|
||||
> (name needs-patch)
|
||||
> EOF
|
||||
$ cat > needs-patch.opam <<EOF
|
||||
> opam-version: "2.0"
|
||||
> EOF
|
||||
$ cat > dune <<EOF
|
||||
> (library (public_name needs-patch) (name needs_patch))
|
||||
> EOF
|
||||
$ cat > needs_patch.ml <<EOF
|
||||
> let msg = "Needs to be patched"
|
||||
> EOF
|
||||
$ cd ..
|
||||
$ tar cf needs-patch.tar needs-patch
|
||||
$ SRC_MD5=$(md5sum needs-patch.tar | cut -f1 -d' ')
|
||||
$ cd needs-patch
|
||||
$ git add -A
|
||||
$ git commit -m "Initial" --quiet
|
||||
$ cat > needs_patch.ml <<EOF
|
||||
> let msg = "Patch successfully applied"
|
||||
> EOF
|
||||
$ git diff > ../required.patch
|
||||
$ git add needs_patch.ml
|
||||
$ git commit -m "First patch" --quiet
|
||||
$ cat > needs_patch.ml <<EOF
|
||||
> let msg = "Patch successfully applied, multiple times"
|
||||
> EOF
|
||||
$ git diff > ../additional.patch
|
||||
$ cd ..
|
||||
$ rm -rf needs-patch
|
||||
$ REQUIRED_PATCH_MD5=$(md5sum required.patch | cut -f1 -d' ')
|
||||
$ ADDITIONAL_PATCH_MD5=$(md5sum additional.patch | cut -f1 -d' ')
|
||||
|
||||
Then we start the oneshot server for both the source and the patch.
|
||||
|
||||
$ echo needs-patch.tar > fake-curls
|
||||
$ SRC_PORT=1
|
||||
$ echo required.patch >> fake-curls
|
||||
$ REQUIRED_PATCH_PORT=2
|
||||
|
||||
We now have the checksums as well as the port numbers, so we can define the
|
||||
package.
|
||||
|
||||
$ mkrepo
|
||||
$ mkpkg needs-patch 0.0.1 <<EOF
|
||||
> build: ["dune" "build" "-p" name "-j" jobs]
|
||||
> patches: ["required.patch"]
|
||||
> url {
|
||||
> src: "http://localhost:$SRC_PORT"
|
||||
> checksum: "md5=$SRC_MD5"
|
||||
> }
|
||||
> extra-source "required.patch" {
|
||||
> src: "http://localhost:$REQUIRED_PATCH_PORT"
|
||||
> checksum: "md5=$REQUIRED_PATCH_MD5"
|
||||
> }
|
||||
> EOF
|
||||
|
||||
Now let's depend on that project with a binary that will display the message
|
||||
that is supposed to get patched.
|
||||
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.15)
|
||||
> (package (name my) (depends needs-patch))
|
||||
> EOF
|
||||
$ cat > dune <<EOF
|
||||
> (executable (public_name display) (libraries needs-patch))
|
||||
> EOF
|
||||
$ cat > display.ml <<EOF
|
||||
> let () = print_endline Needs_patch.msg
|
||||
> EOF
|
||||
|
||||
Lock the dependency, it should generate an a lock dir that references both the
|
||||
url and the extra source.
|
||||
|
||||
$ add_mock_repo_if_needed
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- needs-patch.0.0.1
|
||||
|
||||
$ sed -E 's/md5=[0-9a-f]+/md5=$HASH/g' dune.lock/needs-patch.pkg
|
||||
(version 0.0.1)
|
||||
|
||||
(build
|
||||
(progn
|
||||
(patch required.patch)
|
||||
(run dune build -p %{pkg-self:name} -j %{jobs})))
|
||||
|
||||
(source
|
||||
(fetch
|
||||
(url http://localhost:1)
|
||||
(checksum md5=$HASH)))
|
||||
|
||||
(extra_sources
|
||||
(required.patch
|
||||
(fetch
|
||||
(url http://localhost:2)
|
||||
(checksum md5=$HASH))))
|
||||
|
||||
Running the binary should download the tarball & patch, build them and show the
|
||||
correct, patched, message:
|
||||
|
||||
$ dune exec ./display.exe
|
||||
Patch successfully applied
|
||||
|
||||
Set up a new version of the package which has multiple `extra-sources`, the
|
||||
application order of them mattering:
|
||||
|
||||
$ echo needs-patch.tar >> fake-curls
|
||||
$ SRC_PORT=3
|
||||
$ echo required.patch >> fake-curls
|
||||
$ REQUIRED_PATCH_PORT=4
|
||||
$ echo additional.patch >> fake-curls
|
||||
$ ADDITIONAL_PATCH_PORT=5
|
||||
|
||||
$ mkpkg needs-patch 0.0.2 <<EOF
|
||||
> build: ["dune" "build" "-p" name "-j" jobs]
|
||||
> patches: ["required.patch" "additional.patch"]
|
||||
> url {
|
||||
> src: "http://localhost:$SRC_PORT"
|
||||
> checksum: "md5=$SRC_MD5"
|
||||
> }
|
||||
> extra-source "required.patch" {
|
||||
> src: "http://localhost:$REQUIRED_PATCH_PORT"
|
||||
> checksum: "md5=$REQUIRED_PATCH_MD5"
|
||||
> }
|
||||
> extra-source "additional.patch" {
|
||||
> src: "http://localhost:$ADDITIONAL_PATCH_PORT"
|
||||
> checksum: "md5=$ADDITIONAL_PATCH_MD5"
|
||||
> }
|
||||
> EOF
|
||||
|
||||
Lock the project to use that new package
|
||||
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- needs-patch.0.0.2
|
||||
|
||||
Running the binary should work and output the double patched message:
|
||||
|
||||
$ dune exec ./display.exe
|
||||
Patch successfully applied, multiple times
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
Testing that files are only fetched once.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
No need to set DUNE_CACHE (enabled by default) as the
|
||||
fetch rules are always considered safe to cache, but we'll set a custom
|
||||
directory for the shared cache.
|
||||
|
||||
$ export DUNE_CACHE_ROOT=$(pwd)/dune-cache
|
||||
$ unset DUNE_CACHE
|
||||
|
||||
Set up a project that depends on a package that is being downloaded
|
||||
|
||||
$ make_lockdir
|
||||
$ echo "Contents" > tar-contents
|
||||
$ CONTENT_CHECKSUM=$(md5sum tar-contents | cut -f1 -d' ')
|
||||
$ tar cf test.tar tar-contents
|
||||
$ echo test.tar > fake-curls
|
||||
$ SRC_PORT=1
|
||||
$ SRC_CHECKSUM=$(md5sum test.tar | cut -f1 -d' ')
|
||||
$ cat >dune.lock/test.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (source
|
||||
> (fetch
|
||||
> (url http://localhost:$SRC_PORT)
|
||||
> (checksum md5=$SRC_CHECKSUM)))
|
||||
> EOF
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.17)
|
||||
> (package (name my) (depends test) (allow_empty))
|
||||
> EOF
|
||||
|
||||
The first build should succeed, fetching the source, populating the cache and
|
||||
disabling the download of the source a second time.
|
||||
|
||||
$ build_pkg test
|
||||
|
||||
Make sure that the file that was fetched is in the cache:
|
||||
|
||||
$ find $DUNE_CACHE_ROOT/files -type f -exec md5sum {} \; | grep --quiet $CONTENT_CHECKSUM
|
||||
|
||||
Cleaning the project to force rebuilding. If we attempt to build without the
|
||||
cache, it will fail, as the source is 404 now:
|
||||
|
||||
$ dune clean
|
||||
$ export DUNE_CACHE=disabled
|
||||
$ build_pkg test
|
||||
File "dune.lock/test.pkg", line 4, characters 7-25:
|
||||
4 | (url http://localhost:1)
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
Error: download failed with code 404
|
||||
|
||||
[1]
|
||||
|
||||
However when enabling the cache again, the file that was fetched in the first
|
||||
build should be retrieved from the cache and the build succeed:
|
||||
|
||||
$ dune clean
|
||||
$ export DUNE_CACHE=enabled
|
||||
$ build_pkg test
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
Test that dune can fetch local sources.
|
||||
|
||||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
|
||||
Make a local source archive:
|
||||
$ mkdir src
|
||||
$ echo hello > src/a.txt
|
||||
$ echo world > src/b.txt
|
||||
$ tar -czf src.tar.gz src
|
||||
|
||||
Build a package that uses the archive as its source:
|
||||
$ mkpkg foo <<EOF
|
||||
> url {
|
||||
> src: "$PWD/src.tar.gz"
|
||||
> }
|
||||
> EOF
|
||||
$ add_mock_repo_if_needed
|
||||
$ solve foo
|
||||
Solution for dune.lock:
|
||||
- foo.0.0.1
|
||||
$ build_pkg foo
|
||||
$ cat _build/_private/default/.pkg/foo/source/*
|
||||
hello
|
||||
world
|
||||
|
||||
$ dune clean
|
||||
|
||||
Build a package that uses the src directory as its source:
|
||||
$ mkpkg foo <<EOF
|
||||
> url {
|
||||
> src: "$PWD/src"
|
||||
> }
|
||||
> EOF
|
||||
$ add_mock_repo_if_needed
|
||||
$ solve foo
|
||||
Solution for dune.lock:
|
||||
- foo.0.0.1
|
||||
$ build_pkg foo
|
||||
$ cat _build/_private/default/.pkg/foo/source/*
|
||||
hello
|
||||
world
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
Here we test the file-depends field in pkg1.config. When a package has been
|
||||
installed, the .config file can also be included. This can have a file-depends
|
||||
field which is a list of external files, together with their checksums, that
|
||||
the package depends on. We make sure that such a package really does depend on
|
||||
the files found in files-depend.
|
||||
|
||||
$ . ./helpers.sh
|
||||
$ make_lockdir
|
||||
|
||||
$ foo=$PWD/foo
|
||||
> cat > dune.lock/file-depends.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (build
|
||||
> (system "\| echo Building file-depends
|
||||
> "\| cat > file-depends.config <<EOF
|
||||
> "\| opam-version: "2.0"
|
||||
> "\| file-depends: [ "$foo" "md5=00000000000000000000000000000000" ]
|
||||
> "\| EOF
|
||||
> ))
|
||||
> EOF
|
||||
|
||||
Word of warning: the opam libraries will quietly discard the file-depends field if the
|
||||
checksum is not parsable.
|
||||
|
||||
Now we make a package depending on file-depends.
|
||||
|
||||
$ cat > dune.lock/dep.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (depends file-depends)
|
||||
> (build
|
||||
> (system "echo Building dep"))
|
||||
> EOF
|
||||
|
||||
$ cat > foo <<EOF
|
||||
> Hello
|
||||
> EOF
|
||||
|
||||
Building dep should show both of them as being built.
|
||||
|
||||
$ build_pkg dep
|
||||
Building file-depends
|
||||
Building dep
|
||||
|
||||
Building again causes no rebuild as expected.
|
||||
|
||||
$ build_pkg dep
|
||||
|
||||
Changing foo should cause foo to be rebuilt.
|
||||
|
||||
$ cat > foo <<EOF
|
||||
> World
|
||||
> EOF
|
||||
|
||||
CR-someday alizter: This is broken, no rebuild is done.
|
||||
$ build_pkg dep
|
||||
|
||||
Removing foo should cause an error due to the missing file.
|
||||
|
||||
$ rm foo
|
||||
|
||||
CR-someday alizter: This is broken, no rebuild is done.
|
||||
$ build_pkg dep
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
Demonstrate the handling of findlib directories that don't exist
|
||||
|
||||
Reproduces #11405
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ mkdir external_sources
|
||||
|
||||
$ cat >external_sources/META <<EOF
|
||||
> package "yes" (
|
||||
> directory = "yes"
|
||||
> version = "0.0.1"
|
||||
> exists_if = "yes.cma"
|
||||
> )
|
||||
> package "no" (
|
||||
> directory = "no"
|
||||
> version = "0.0.1"
|
||||
> exists_if = "no.cma"
|
||||
> )
|
||||
> EOF
|
||||
|
||||
$ cat >external_sources/mypkg.install <<EOF
|
||||
> lib: [
|
||||
> "META"
|
||||
> "yes/yes.cma" {"yes/yes.cma"}
|
||||
> ]
|
||||
> EOF
|
||||
|
||||
$ mkdir external_sources/yes
|
||||
$ touch external_sources/yes/yes.cma
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.17)
|
||||
> EOF
|
||||
|
||||
$ mkdir dune.lock
|
||||
|
||||
$ cat >dune.lock/lock.dune <<EOF
|
||||
> (lang package 0.1)
|
||||
> EOF
|
||||
|
||||
$ cat >dune.lock/mypkg.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (source (copy $PWD/external_sources))
|
||||
> EOF
|
||||
|
||||
$ touch foo.ml
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (executable
|
||||
> (libraries mypkg.yes)
|
||||
> (name foo))
|
||||
> EOF
|
||||
|
||||
No errors here as 'yes' actually exists
|
||||
$ dune build foo.exe
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (executable
|
||||
> (libraries mypkg.no)
|
||||
> (name foo))
|
||||
> EOF
|
||||
|
||||
Clearer error here as we really depend on non-existing 'no'
|
||||
$ dune build foo.exe
|
||||
File "dune", line 2, characters 12-20:
|
||||
2 | (libraries mypkg.no)
|
||||
^^^^^^^^
|
||||
Error: Library "mypkg.no" in
|
||||
_build/_private/default/.pkg/mypkg/target/lib/mypkg/no is hidden (unsatisfied
|
||||
'exists_if').
|
||||
-> required by _build/default/.foo.eobjs/native/dune__exe__Foo.cmx
|
||||
-> required by _build/default/foo.exe
|
||||
[1]
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
Repro `dune exec --watch` crash with pkg management
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ mkdir external_sources
|
||||
$ cat >external_sources/dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package (name mypkg))
|
||||
> EOF
|
||||
$ cat >external_sources/dune <<EOF
|
||||
> (library
|
||||
> (public_name mypkg.lib)
|
||||
> (name test_lib))
|
||||
> EOF
|
||||
$ cat >external_sources/test_lib.ml <<EOF
|
||||
> let x = "hello"
|
||||
> EOF
|
||||
|
||||
Now we set up a lock file with this package and then attempt to use it:
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> EOF
|
||||
|
||||
$ mkdir dune.lock
|
||||
$ cat >dune.lock/lock.dune <<EOF
|
||||
> (lang package 0.1)
|
||||
> EOF
|
||||
|
||||
$ cat >dune.lock/mypkg.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (source (copy $PWD/external_sources))
|
||||
> (build
|
||||
> (run dune build --release --promote-install-file=true . @install))
|
||||
> EOF
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (dirs (:standard \ external_sources))
|
||||
> (executable
|
||||
> (name x)
|
||||
> (libraries mypkg.lib))
|
||||
> EOF
|
||||
|
||||
$ cat >x.ml <<EOF
|
||||
> let () = print_endline Test_lib.x
|
||||
> EOF
|
||||
|
||||
$ dune exec -w ./x.exe > output.log 2>&1 &
|
||||
$ PID=$!
|
||||
|
||||
$ TIME_WAITED=0
|
||||
$ MAX_WAIT_TIME=20
|
||||
$ SLEEP_INTERVAL=1
|
||||
$ while [ $(cat output.log | wc -l) -lt 2 ] && [ "$TIME_WAITED" -lt "$MAX_WAIT_TIME" ]; do
|
||||
> sleep 0.1
|
||||
> TIME_WAITED=$((TIME_WAITED + SLEEP_INTERVAL))
|
||||
> done
|
||||
|
||||
$ cat output.log | sort
|
||||
Success, waiting for filesystem changes...
|
||||
hello
|
||||
$ kill $PID
|
||||
$ wait $PID
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
This test attempts to build the ocaml index while depending on a library
|
||||
installed through a lock file.
|
||||
|
||||
We set up a library that will be installed as part of the package:
|
||||
|
||||
$ mkdir external_sources
|
||||
$ cat >external_sources/dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package (name mypkg))
|
||||
> EOF
|
||||
$ cat >external_sources/dune <<EOF
|
||||
> (library
|
||||
> (public_name mypkg.lib)
|
||||
> (name test_lib))
|
||||
> EOF
|
||||
$ cat >external_sources/test_lib.ml <<EOF
|
||||
> let x = ()
|
||||
> EOF
|
||||
|
||||
We put the actual build in a separate directory, so we don't have to ignore
|
||||
the package directory in the dune file:
|
||||
$ mkdir actual
|
||||
$ cd actual
|
||||
|
||||
Now we set up a lock file with this package and then attempt to use it:
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> EOF
|
||||
|
||||
$ mkdir dune.lock
|
||||
$ cat >dune.lock/lock.dune <<EOF
|
||||
> (lang package 0.1)
|
||||
> EOF
|
||||
|
||||
$ cat >dune.lock/mypkg.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (source (copy $PWD/../external_sources))
|
||||
> (build (run dune build --release --promote-install-file=true . @install))
|
||||
> EOF
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (library
|
||||
> (name foo)
|
||||
> (libraries mypkg.lib))
|
||||
> EOF
|
||||
|
||||
$ cat >foo.ml <<EOF
|
||||
> let () = Test_lib.x
|
||||
> EOF
|
||||
|
||||
$ mkdir .bin
|
||||
$ cat > .bin/ocaml-index <<EOF
|
||||
> #!/usr/bin/env sh
|
||||
> exit 1
|
||||
> EOF
|
||||
|
||||
$ chmod +x .bin/ocaml-index
|
||||
$ export PATH="$PWD/.bin:$PATH"
|
||||
|
||||
$ dune build @ocaml-index
|
||||
File ".foo.objs/_unknown_", line 1, characters 0-0:
|
||||
Command exited with code 1.
|
||||
[1]
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
Package conflicts are ignored when dune-projects contains multiple conflicts
|
||||
|
||||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
$ mkpkg bar
|
||||
|
||||
A package which depends on a single package and also conflicts with the same package:
|
||||
$ solve_project << EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name foo)
|
||||
> (allow_empty)
|
||||
> (depends bar)
|
||||
> (conflicts bar))
|
||||
> EOF
|
||||
Error: Unable to solve dependencies for the following lock directories:
|
||||
Lock directory dune.lock:
|
||||
Couldn't solve the package dependency formula.
|
||||
Selected candidates: foo.dev
|
||||
- bar -> (problem)
|
||||
No usable implementations:
|
||||
bar.0.0.1: Package does not satisfy constraints of local package foo
|
||||
[1]
|
||||
|
||||
Now add an additional conflict on a non-existant package "baz". Dune should continue to fail to find a solution due to the conflict with "bar".
|
||||
$ solve_project << EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name foo)
|
||||
> (allow_empty)
|
||||
> (depends bar)
|
||||
> (conflicts bar baz))
|
||||
> EOF
|
||||
Error: Unable to solve dependencies for the following lock directories:
|
||||
Lock directory dune.lock:
|
||||
Couldn't solve the package dependency formula.
|
||||
Selected candidates: foo.dev
|
||||
- bar -> (problem)
|
||||
No usable implementations:
|
||||
bar.0.0.1: Package does not satisfy constraints of local package foo
|
||||
[1]
|
||||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
Things should be the same whether dependencies are specified or not.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ make_lockdir
|
||||
|
||||
If we have a package we depend on
|
||||
|
||||
$ mkdir dependency-source
|
||||
$ cat >dune.lock/dependency.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (source (copy $PWD/dependency-source))
|
||||
> EOF
|
||||
|
||||
And we have a package we want to build
|
||||
|
||||
$ mkdir test-source
|
||||
$ cat >dune.lock/test.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (source (copy $PWD/test-source))
|
||||
> (build
|
||||
> (system "command -v cat > /dev/null 2>&1 || echo no cat"))
|
||||
> EOF
|
||||
$ build_pkg test
|
||||
|
||||
Now it fails since adding the dependency modified PATH.
|
||||
|
||||
$ cat >dune.lock/test.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (source (copy $PWD/test-source))
|
||||
> ; adding deps breaks cat
|
||||
> (depends dependency)
|
||||
> (build
|
||||
> (system "command -v cat > /dev/null 2>&1 || echo no cat"))
|
||||
> EOF
|
||||
$ build_pkg test
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
We want to make sure our OPAM-repository in git support works well.
|
||||
|
||||
$ . ../git-helpers.sh
|
||||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
$ mkpkg foo 1.0 <<EOF
|
||||
> EOF
|
||||
$ cd mock-opam-repository
|
||||
$ git init --quiet
|
||||
$ git add -A
|
||||
$ git commit --quiet -m "foo 1.0"
|
||||
$ cd ..
|
||||
|
||||
We'll set up a project that uses (only this) this repository, so doesn't use
|
||||
:standard:
|
||||
|
||||
$ add_mock_repo_if_needed "git+file://$PWD/mock-opam-repository"
|
||||
|
||||
We depend on the foo package
|
||||
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.10)
|
||||
>
|
||||
> (package
|
||||
> (name bar)
|
||||
> (depends foo))
|
||||
> EOF
|
||||
|
||||
Locking should produce the newest package from the repo
|
||||
|
||||
$ mkdir dune-cache
|
||||
$ XDG_CACHE_HOME=$PWD/dune-cache dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- foo.1.0
|
||||
|
||||
Now let's assume a new version of foo is released.
|
||||
|
||||
$ mkpkg foo 1.1 <<EOF
|
||||
> EOF
|
||||
$ cd mock-opam-repository
|
||||
$ git add -A
|
||||
$ git commit --quiet -m "foo 1.1 -> new version"
|
||||
$ cd ..
|
||||
|
||||
Locking should update the git repo in our cache folder and give us the newer
|
||||
version in the lock file
|
||||
|
||||
$ XDG_CACHE_HOME=$PWD/dune-cache dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- foo.1.1
|
||||
|
||||
If the package selected has some additional files that are supposed to be
|
||||
included for building, these should also be part of the lockfile.
|
||||
|
||||
So if we create an extra-file (in OPAM parlance) and attach it to foo.1.2 it
|
||||
should also be included.
|
||||
|
||||
$ FILES_NAME=hello.txt
|
||||
$ cat > $FILES_NAME <<EOF
|
||||
> Hello World
|
||||
> EOF
|
||||
$ FILES_CHECKSUM=e59ff97941044f85df5297e1c302d260
|
||||
$ mkpkg foo 1.2 <<EOF
|
||||
> EOF
|
||||
$ echo "extra-files: [\"$FILES_NAME\" \"md5=$FILES_CHECKSUM\"]" >> mock-opam-repository/packages/foo/foo.1.2/opam
|
||||
$ FILES_FOLDER=mock-opam-repository/packages/foo/foo.1.2/files/
|
||||
$ mkdir -p "$FILES_FOLDER"
|
||||
$ mv "$FILES_NAME" "$FILES_FOLDER/$FILES_NAME"
|
||||
$ cd mock-opam-repository
|
||||
$ git add -A
|
||||
$ git commit --quiet -m "foo 1.2 with files"
|
||||
$ cd ..
|
||||
|
||||
Locking should be successful and it should include the additional file
|
||||
|
||||
$ XDG_CACHE_HOME=$PWD/dune-cache dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- foo.1.2
|
||||
|
||||
$ find dune.lock | sort
|
||||
dune.lock
|
||||
dune.lock/foo.files
|
||||
dune.lock/foo.files/hello.txt
|
||||
dune.lock/foo.pkg
|
||||
dune.lock/lock.dune
|
||||
|
||||
The extra-file should have the same content as the original file, we determine
|
||||
that by hashing with the checksum that we expected in the OPAM file
|
||||
|
||||
$ cmp -s dune.lock/foo.files/$FILES_NAME "$FILES_FOLDER/$FILES_NAME" && echo "The contents match"
|
||||
The contents match
|
||||
|
||||
The git repos support repo should also be able to handle unusual objects in our
|
||||
tree, which can e.g. happen with submodules.
|
||||
|
||||
$ cd mock-opam-repository
|
||||
$ PARENT=$(git rev-parse HEAD)
|
||||
|
||||
To make this a bit easier we use some git plumbing commands to reproduce it.
|
||||
First we create a commit object in the index and write a tree containing this
|
||||
commit (pointing to nowhere):
|
||||
|
||||
$ git update-index --add --cacheinfo 160000,0000000000000000000000000000000000000001,dangling-commit-in-tree
|
||||
$ TREE=$(git write-tree)
|
||||
|
||||
Then we create a commit with the tree and our HEAD as a parent commit
|
||||
|
||||
$ CURRENT=$(echo "Added a dangling commit object" | git commit-tree $TREE -p $PARENT)
|
||||
|
||||
Then we make this new commit the one that our branch is pointing to.
|
||||
|
||||
$ git reset --hard -q $CURRENT
|
||||
|
||||
Thus ls-tree should now also contain a commit object:
|
||||
|
||||
$ git ls-tree -r HEAD | awk '{ printf "%s %s\n",$2,$4; }' | sort
|
||||
blob packages/foo/foo.1.0/opam
|
||||
blob packages/foo/foo.1.1/opam
|
||||
blob packages/foo/foo.1.2/files/hello.txt
|
||||
blob packages/foo/foo.1.2/opam
|
||||
commit dangling-commit-in-tree
|
||||
$ cd ..
|
||||
|
||||
With this set up in place, locking should still work as the commit is not
|
||||
relevant
|
||||
|
||||
$ XDG_CACHE_HOME=$PWD/dune-cache dune pkg lock 2> /dev/null && echo "Solution found"
|
||||
Solution found
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
Test fetching from git
|
||||
|
||||
$ . ../git-helpers.sh
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ mkdir somerepo
|
||||
$ cd somerepo
|
||||
$ git init --quiet
|
||||
$ echo "hello world" > foo
|
||||
$ git add foo
|
||||
$ git commit -am _ --quiet
|
||||
$ cd ..
|
||||
|
||||
$ MYGITREPO=$PWD/somerepo
|
||||
|
||||
$ mkdir foo && cd foo
|
||||
$ make_lockdir
|
||||
$ cat >dune.lock/test.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (source (fetch (url "git+file://$MYGITREPO")))
|
||||
> (build (run cat foo))
|
||||
> EOF
|
||||
|
||||
$ build_pkg test
|
||||
hello world
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
$ . ../git-helpers.sh
|
||||
$ . ./helpers.sh
|
||||
|
||||
When we fetch a package source we should also fetch any submodules. Since we
|
||||
will use the file protocol for git submodules we will need to explicitly enable
|
||||
it as it is disabled for security purposes.
|
||||
|
||||
$ export GIT_ALLOW_PROTOCOL=file
|
||||
|
||||
This repository will be a submodule in our main repository.
|
||||
$ mkdir someotherrepo
|
||||
$ cd someotherrepo
|
||||
$ git init --quiet
|
||||
$ echo "world" > bar
|
||||
$ git add bar
|
||||
$ git commit -am _ --quiet
|
||||
$ cd ..
|
||||
$ SOMEOTHERREPO=$PWD/someotherrepo
|
||||
|
||||
We create a repository for the package that we wish to build that has
|
||||
someotherrepo as a submodule.
|
||||
$ mkdir somerepo
|
||||
$ cd somerepo
|
||||
$ git init --quiet
|
||||
$ echo "hello" > foo
|
||||
$ git submodule add --quiet $SOMEOTHERREPO mysubmodule
|
||||
$ git add foo mysubmodule .gitmodules
|
||||
$ git commit -am _ --quiet
|
||||
$ cd ..
|
||||
$ SOMEREPO=$PWD/somerepo
|
||||
|
||||
$ mkdir foo && cd foo
|
||||
$ make_lockdir
|
||||
$ cat >dune.lock/test.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (source (fetch (url "git+file://$SOMEREPO")))
|
||||
> (build (progn (run cat foo) (run cat mysubmodule/bar)))
|
||||
> EOF
|
||||
|
||||
Building this package should pull in both repositories. At the moment this is
|
||||
not the case and only somerepo is pulled.
|
||||
|
||||
$ build_pkg test 2>&1 | sed -E 's|.*/cat|cat|'
|
||||
hello
|
||||
world
|
||||
When the above works it should act like:
|
||||
|
||||
$ make_lockdir
|
||||
$ cat >dune.lock/test.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (source (fetch (url "git+file://$SOMEREPO")))
|
||||
> (build
|
||||
> (progn
|
||||
> (run cp -r $SOMEOTHERREPO/bar mysubmodule)
|
||||
> (run cat foo)
|
||||
> (run cat mysubmodule/bar)))
|
||||
> EOF
|
||||
|
||||
$ build_pkg test
|
||||
hello
|
||||
world
|
||||
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
Test that dune supports lockfiles with md5, sha256 and sha512 hashes.
|
||||
|
||||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
$ add_mock_repo_if_needed
|
||||
|
||||
$ mkpkg with-md5 <<EOF
|
||||
> url {
|
||||
> src: "file://with-md5"
|
||||
> checksum: [
|
||||
> "md5=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
> ]
|
||||
> }
|
||||
> EOF
|
||||
|
||||
$ mkpkg with-sha256 <<EOF
|
||||
> url {
|
||||
> src: "file://with-sha256"
|
||||
> checksum: [
|
||||
> "sha256=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
|
||||
> ]
|
||||
> }
|
||||
> EOF
|
||||
|
||||
$ mkpkg with-sha512 <<EOF
|
||||
> url {
|
||||
> src: "file://with-sha512"
|
||||
> checksum: [
|
||||
> "sha512=cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
|
||||
> ]
|
||||
> }
|
||||
> EOF
|
||||
|
||||
This package uses multiple hashing algorithms. Currently dune will just add the
|
||||
first checksum to the lockfile for this package.
|
||||
|
||||
$ mkpkg with-all <<EOF
|
||||
> url {
|
||||
> src: "file://with-all"
|
||||
> checksum: [
|
||||
> "md5=dddddddddddddddddddddddddddddddd"
|
||||
> "sha256=eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
|
||||
> "sha512=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
> ]
|
||||
> }
|
||||
> extra-source "fixes.patch" {
|
||||
> src: "https://unimportant.url/unused.patch"
|
||||
> checksum: [
|
||||
> "md5=00000000000000000000000000000000"
|
||||
> "sha256=1111111111111111111111111111111111111111111111111111111111111111"
|
||||
> "sha512=22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
|
||||
> ]
|
||||
> }
|
||||
> EOF
|
||||
|
||||
$ solve with-md5 with-sha256 with-sha512 with-all
|
||||
Solution for dune.lock:
|
||||
- with-all.0.0.1
|
||||
- with-md5.0.0.1
|
||||
- with-sha256.0.0.1
|
||||
- with-sha512.0.0.1
|
||||
|
||||
$ cat dune.lock/*
|
||||
(lang package 0.1)
|
||||
|
||||
(dependency_hash 32180cf311133b30d0b5be2a40c89f43)
|
||||
|
||||
(repositories
|
||||
(complete false)
|
||||
(used))
|
||||
(version 0.0.1)
|
||||
|
||||
(source
|
||||
(fetch
|
||||
(url file://with-all)
|
||||
(checksum md5=dddddddddddddddddddddddddddddddd)))
|
||||
|
||||
(extra_sources
|
||||
(fixes.patch
|
||||
(fetch
|
||||
(url https://unimportant.url/unused.patch)
|
||||
(checksum md5=00000000000000000000000000000000))))
|
||||
(version 0.0.1)
|
||||
|
||||
(source
|
||||
(fetch
|
||||
(url file://with-md5)
|
||||
(checksum md5=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)))
|
||||
(version 0.0.1)
|
||||
|
||||
(source
|
||||
(fetch
|
||||
(url file://with-sha256)
|
||||
(checksum
|
||||
sha256=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb)))
|
||||
(version 0.0.1)
|
||||
|
||||
(source
|
||||
(fetch
|
||||
(url file://with-sha512)
|
||||
(checksum
|
||||
sha512=cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc)))
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
export XDG_CACHE_HOME="$PWD/.cache"
|
||||
|
||||
# Set the default platform for the purposes of solving dependencies so that the
|
||||
# output of tests is platform-independent.
|
||||
export DUNE_CONFIG__OS=linux
|
||||
export DUNE_CONFIG__ARCH=x86_64
|
||||
export DUNE_CONFIG__OS_FAMILY=debian
|
||||
export DUNE_CONFIG__OS_DISTRIBUTION=ubuntu
|
||||
export DUNE_CONFIG__OS_VERSION=24.11
|
||||
export DUNE_CONFIG__SYS_OCAML_VERSION=5.4.0+fake
|
||||
|
||||
dune="dune"
|
||||
|
||||
pkg_root="_build/_private/default/.pkg"
|
||||
|
||||
build_pkg() {
|
||||
$dune build $pkg_root/$1/target/
|
||||
}
|
||||
|
||||
show_pkg() {
|
||||
find $pkg_root/$1 | sort | sed "s#$pkg_root/$1##"
|
||||
}
|
||||
|
||||
strip_sandbox() {
|
||||
sed -E 's#[^ ]*.sandbox/[^/]+#$SANDBOX#g'
|
||||
}
|
||||
|
||||
show_pkg_targets() {
|
||||
find $pkg_root/$1/target | sort | sed "s#$pkg_root/$1/target##"
|
||||
}
|
||||
|
||||
show_pkg_cookie() {
|
||||
$dune internal dump $pkg_root/$1/target/cookie
|
||||
}
|
||||
|
||||
mock_packages="mock-opam-repository/packages"
|
||||
|
||||
mkrepo() {
|
||||
mkdir -p $mock_packages
|
||||
}
|
||||
|
||||
mkpkg() {
|
||||
name=$1
|
||||
if [ "$#" -eq "1" ]
|
||||
then
|
||||
version="0.0.1"
|
||||
else
|
||||
version="$2"
|
||||
fi
|
||||
mkdir -p $mock_packages/$name/$name.$version
|
||||
echo 'opam-version: "2.0"' > $mock_packages/$name/$name.$version/opam
|
||||
cat >>$mock_packages/$name/$name.$version/opam
|
||||
}
|
||||
|
||||
add_mock_repo_if_needed() {
|
||||
# default, but can be overridden, e.g. if git is required
|
||||
repo="${1:-file://$(pwd)/mock-opam-repository}"
|
||||
|
||||
if [ ! -e dune-workspace ]
|
||||
then
|
||||
cat >dune-workspace <<EOF
|
||||
(lang dune 3.10)
|
||||
(lock_dir
|
||||
(repositories mock))
|
||||
(repository
|
||||
(name mock)
|
||||
(url "${repo}"))
|
||||
EOF
|
||||
else
|
||||
if ! grep '(name mock)' > /dev/null dune-workspace
|
||||
then
|
||||
# add the repo definition
|
||||
cat >>dune-workspace <<EOF
|
||||
(repository
|
||||
(name mock)
|
||||
(url "${repo}"))
|
||||
EOF
|
||||
|
||||
# reference the repo
|
||||
if grep -s '(repositories'
|
||||
then
|
||||
sed -i '' -e 's/(repositories \(.*\))/(repositories mock \1)/' dune-workspace
|
||||
else
|
||||
cat >>dune-workspace <<EOF
|
||||
(lock_dir
|
||||
(repositories mock))
|
||||
EOF
|
||||
fi
|
||||
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
make_lockpkg() {
|
||||
local dir="dune.lock"
|
||||
mkdir -p $dir
|
||||
local f="$dir/$1.pkg"
|
||||
cat >$f
|
||||
}
|
||||
|
||||
solve_project() {
|
||||
cat >dune-project
|
||||
add_mock_repo_if_needed
|
||||
dune pkg lock $@
|
||||
}
|
||||
|
||||
make_lockdir() {
|
||||
mkdir -p dune.lock
|
||||
cat >dune.lock/lock.dune <<EOF
|
||||
(lang package 0.1)
|
||||
(repositories (complete true))
|
||||
EOF
|
||||
}
|
||||
|
||||
make_project() {
|
||||
cat <<EOF
|
||||
(lang dune 3.11)
|
||||
(package
|
||||
(name x)
|
||||
(allow_empty)
|
||||
(depends $@))
|
||||
EOF
|
||||
}
|
||||
|
||||
print_source() {
|
||||
cat dune.lock/$1.pkg | sed -n "/source/,//p" | sed "s#$PWD#PWD#g" | tr '\n' ' '| tr -s " "
|
||||
}
|
||||
|
||||
solve() {
|
||||
make_project $@ | solve_project
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
When building a project with -p we should ignore the lock directory. This is so
|
||||
that packages with lockdirs in their source archive can be built by opam
|
||||
without using locked dependencies.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ make_lockdir
|
||||
|
||||
$ cat >dune.lock/test.pkg <<EOF
|
||||
> (build
|
||||
> (run echo "I have not been ignored."))
|
||||
> EOF
|
||||
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name foo)
|
||||
> (allow_empty)
|
||||
> (depends test))
|
||||
> EOF
|
||||
|
||||
$ dune build @install -p foo
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
Test that shows what happens when dune.lock is ignored.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ make_lockdir
|
||||
$ cat >dune.lock/test.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (build
|
||||
> (progn
|
||||
> (run touch foo.ml)
|
||||
> (patch foo.patch)))
|
||||
> EOF
|
||||
$ mkdir dune.lock/test.files
|
||||
$ cat > dune.lock/test.files/foo.patch <<EOF
|
||||
> diff --git a/foo.ml b/foo.ml
|
||||
> index b69a69a5a..ea988f6bd 100644
|
||||
> --- a/foo.ml
|
||||
> +++ b/foo.ml
|
||||
> @@ -0,0 +1 @@
|
||||
> +let () = print_endline "Hello, World!"
|
||||
> EOF
|
||||
|
||||
$ mkdir src
|
||||
$ cat > src/dune <<EOF
|
||||
> (executable
|
||||
> (name foo))
|
||||
> EOF
|
||||
$ cat > src/foo.ml <<EOF
|
||||
> let () = ()
|
||||
> EOF
|
||||
> cat > dune-project <<EOF
|
||||
> (lang dune 3.16)
|
||||
> EOF
|
||||
|
||||
Building test works when the dune.lock is visible to dune.
|
||||
|
||||
$ build_pkg test
|
||||
|
||||
Now the project is changed to only include src (which effectively ignores
|
||||
dune.lock):
|
||||
|
||||
$ cat > dune <<EOF
|
||||
> (dirs src)
|
||||
> EOF
|
||||
|
||||
Building fails as the patch cannot be found anymore
|
||||
|
||||
$ build_pkg test 2>&1 | sed 's|\.sandbox/[a-f0-9]*/|.sandbox/<hash>/|'
|
||||
Error:
|
||||
open(_build/.sandbox/<hash>/_private/default/.pkg/test/source/foo.patch): No such file or directory
|
||||
-> required by _build/_private/default/.pkg/test/target
|
||||
|
||||
And the backage cannot be shown:
|
||||
|
||||
$ show_pkg test
|
||||
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
By default, we introduce a constraint on in the build plan that will require
|
||||
the dune version to match the version of dune being used to generate the
|
||||
constraint. On another hand, we ensure `dune` can be used as a declared
|
||||
dependency.
|
||||
|
||||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
|
||||
$ mkpkg dune 3.11.0 <<EOF
|
||||
> EOF
|
||||
|
||||
$ test() {
|
||||
> mkpkg foo <<EOF
|
||||
> depends: [ "dune" {<= "$1"} ]
|
||||
> EOF
|
||||
> solve foo
|
||||
> }
|
||||
|
||||
$ test "2.0.0" 2>&1 | sed -E 's/3.[0-9]+/3.XX/g'
|
||||
Error: Unable to solve dependencies for the following lock directories:
|
||||
Lock directory dune.lock:
|
||||
Couldn't solve the package dependency formula.
|
||||
Selected candidates: foo.0.0.1 x.dev
|
||||
- dune -> (problem)
|
||||
User requested = 3.XX
|
||||
Rejected candidates:
|
||||
dune.3.XX.0: Incompatible with restriction: = 3.XX
|
||||
$ test "4.0.0"
|
||||
Solution for dune.lock:
|
||||
- foo.0.0.1
|
||||
|
||||
Create a fake project and ensure `dune` can be used as a dependency:
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.13)
|
||||
> (package
|
||||
> (name bar)
|
||||
> (allow_empty)
|
||||
> (depends dune))
|
||||
> EOF
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
(no dependencies to lock)
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
Install actions should have the switch directory prepared:
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ make_lockdir
|
||||
$ cat >dune.lock/test.pkg <<'EOF'
|
||||
> (version 0.0.1)
|
||||
> (install (system "find %{prefix} | sort"))
|
||||
> EOF
|
||||
|
||||
$ build_pkg test
|
||||
../target
|
||||
../target/bin
|
||||
../target/doc
|
||||
../target/doc/test
|
||||
../target/etc
|
||||
../target/etc/test
|
||||
../target/lib
|
||||
../target/lib/stublibs
|
||||
../target/lib/test
|
||||
../target/lib/toplevel
|
||||
../target/man
|
||||
../target/sbin
|
||||
../target/share
|
||||
../target/share/test
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
Testing install actions
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ make_lockdir
|
||||
$ cat >dune.lock/test.pkg <<'EOF'
|
||||
> (version 0.0.1)
|
||||
> (install (system "echo foobar; mkdir -p %{lib}; touch %{lib}/xxx"))
|
||||
> EOF
|
||||
|
||||
$ build_pkg test
|
||||
foobar
|
||||
|
||||
$ export BUILD_PATH_PREFIX_MAP="/PKG_ROOT=test/target:$BUILD_PATH_PREFIX_MAP"
|
||||
|
||||
$ show_pkg_targets test
|
||||
|
||||
/bin
|
||||
/cookie
|
||||
/doc
|
||||
/doc/test
|
||||
/etc
|
||||
/etc/test
|
||||
/lib
|
||||
/lib/stublibs
|
||||
/lib/test
|
||||
/lib/toplevel
|
||||
/lib/xxx
|
||||
/man
|
||||
/sbin
|
||||
/share
|
||||
/share/test
|
||||
|
||||
$ show_pkg_cookie test
|
||||
{ files =
|
||||
map
|
||||
{ LIB_ROOT :
|
||||
[ In_build_dir "_private/default/.pkg/test/target/lib/xxx" ]
|
||||
}
|
||||
; variables = []
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
Use build paths in the install entries of a package
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ make_lockdir
|
||||
|
||||
$ cat >dune.lock/test.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (build
|
||||
> (system "\| cat >test.install <<EOF
|
||||
> "\| bin: [ "?_build/install/default/bin/foo" ]
|
||||
> "\| EOF
|
||||
> ))
|
||||
> EOF
|
||||
|
||||
$ build_pkg test
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
Test missing entries in the .install file
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ make_lockdir
|
||||
$ lockfile() {
|
||||
> cat >dune.lock/test.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (build
|
||||
> (system "echo 'lib: [ \"$1\" ]' > test.install"))
|
||||
> EOF
|
||||
> }
|
||||
|
||||
This should give us a proper error that myfile wasn't generated
|
||||
|
||||
$ lockfile "myfile"
|
||||
$ build_pkg test 2>&1 | sed 's#_build.*_private#$ROOT/_private#'
|
||||
Error: entry
|
||||
$ROOT/_private/default/.pkg/test/source/myfile
|
||||
in
|
||||
$ROOT/_private/default/.pkg/test/source/test.install
|
||||
does not exist
|
||||
-> required by $ROOT/_private/default/.pkg/test/target
|
||||
|
||||
This on the other hand shouldn't error because myfile is optional
|
||||
|
||||
$ lockfile "?myfile"
|
||||
$ build_pkg test
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
Test that installed binaries are visible in dependent packages
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ make_lockdir
|
||||
$ cat >dune.lock/test.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (build
|
||||
> (system "\| echo "#!/bin/sh\necho from test package" > foo;
|
||||
> "\| chmod +x foo;
|
||||
> "\| touch libxxx lib_rootxxx;
|
||||
> "\| cat >test.install <<EOF
|
||||
> "\| bin: [ "foo" ]
|
||||
> "\| lib: [ "libxxx" ]
|
||||
> "\| lib_root: [ "lib_rootxxx" ]
|
||||
> "\| share_root: [ "lib_rootxxx" ]
|
||||
> "\| EOF
|
||||
> ))
|
||||
> EOF
|
||||
|
||||
$ cat >dune.lock/usetest.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (depends test)
|
||||
> (build
|
||||
> (progn
|
||||
> (run foo)
|
||||
> (run mkdir -p %{prefix})))
|
||||
> EOF
|
||||
|
||||
$ build_pkg usetest
|
||||
from test package
|
||||
|
||||
$ show_pkg_targets test
|
||||
|
||||
/bin
|
||||
/bin/foo
|
||||
/cookie
|
||||
/lib
|
||||
/lib/lib_rootxxx
|
||||
/lib/test
|
||||
/lib/test/libxxx
|
||||
/share
|
||||
/share/lib_rootxxx
|
||||
$ show_pkg_cookie test
|
||||
{ files =
|
||||
map
|
||||
{ LIB :
|
||||
[ In_build_dir "_private/default/.pkg/test/target/lib/test/libxxx"
|
||||
]
|
||||
; LIB_ROOT :
|
||||
[ In_build_dir "_private/default/.pkg/test/target/lib/lib_rootxxx"
|
||||
]
|
||||
; BIN : [ In_build_dir "_private/default/.pkg/test/target/bin/foo" ]
|
||||
; SHARE_ROOT :
|
||||
[ In_build_dir
|
||||
"_private/default/.pkg/test/target/share/lib_rootxxx"
|
||||
]
|
||||
}
|
||||
; variables = []
|
||||
}
|
||||
|
||||
It should also be visible in the workspace:
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.9)
|
||||
> EOF
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (rule
|
||||
> (with-stdout-to testout (run %{bin:foo})))
|
||||
> EOF
|
||||
|
||||
$ dune build ./testout && cat _build/default/testout
|
||||
from test package
|
||||
|
|
@ -0,0 +1 @@
|
|||
bad repo file
|
||||
|
|
@ -0,0 +1 @@
|
|||
opam-version: "1.0"
|
||||
|
|
@ -0,0 +1 @@
|
|||
opam-version: "2.0"
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
Test the error cases for invalid opam repositories
|
||||
|
||||
$ . ../helpers.sh
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.8)
|
||||
> (package
|
||||
> (name lockfile_generation_test))
|
||||
> EOF
|
||||
$ add_mock_repo_if_needed "file://$(pwd)/directory-that-does-not-exist"
|
||||
|
||||
$ lock() {
|
||||
> out="$(dune pkg lock 2>&1)"
|
||||
> local code="$?"
|
||||
> echo "$out" | sed 's/character.*:/characters X-X:/g' \
|
||||
> | sed 's/url ".*"/url ../g' \
|
||||
> | grep -v "\^"
|
||||
> return $code
|
||||
> }
|
||||
|
||||
$ lock
|
||||
File "dune-workspace", line 6, characters X-X:
|
||||
6 | (url ..))
|
||||
Error:
|
||||
$TESTCASE_ROOT/directory-that-does-not-exist
|
||||
does not exist
|
||||
[1]
|
||||
|
||||
$ touch empty
|
||||
$ rm dune-workspace
|
||||
$ add_mock_repo_if_needed "file://$(pwd)/empty"
|
||||
$ lock
|
||||
File "dune-workspace", line 6, characters X-X:
|
||||
6 | (url ..))
|
||||
Error:
|
||||
$TESTCASE_ROOT/empty
|
||||
is not a directory
|
||||
[1]
|
||||
|
||||
$ rm dune-workspace
|
||||
$ add_mock_repo_if_needed "file://$(pwd)/no-packages-dir"
|
||||
$ lock
|
||||
File "dune-workspace", line 6, characters X-X:
|
||||
6 | (url ..))
|
||||
Error:
|
||||
$TESTCASE_ROOT/no-packages-dir
|
||||
doesn't look like a path to an opam repository as it lacks a subdirectory
|
||||
named "packages"
|
||||
[1]
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
Having an invalid package dependency that looks like an opam-versioned package
|
||||
gives a good user message rather. It is very likely that users will type
|
||||
foo.1.2.3 for a package version due to the convention in opam.
|
||||
In this case we could also hint at the correct syntax for dune-project files.
|
||||
|
||||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
$ mkpkg foo 1.2.3
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.13)
|
||||
> (package
|
||||
> (name invalid)
|
||||
> (depends foo.1.2.3))
|
||||
> EOF
|
||||
$ add_mock_repo_if_needed
|
||||
|
||||
$ dune pkg lock 2>&1
|
||||
File "dune-project", line 4, characters 10-19:
|
||||
4 | (depends foo.1.2.3))
|
||||
^^^^^^^^^
|
||||
Error: "foo.1.2.3" is an invalid package dependency.
|
||||
Package names can contain letters, numbers, '-', '_' and '+', and need to
|
||||
contain at least a letter.
|
||||
Hint: (foo (= 1.2.3)) would be a correct package dependency
|
||||
[1]
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
Add some build contexts with different environments
|
||||
$ cat >dune-workspace <<EOF
|
||||
> (lang dune 3.8)
|
||||
> (lock_dir
|
||||
> (path dune.lock)
|
||||
> (unset_solver_vars arch os-distribution os os-family os-version sys-ocaml-version))
|
||||
> (lock_dir
|
||||
> (path dune.linux.lock)
|
||||
> (solver_env
|
||||
> (os linux))
|
||||
> (unset_solver_vars arch os-distribution os-family os-version sys-ocaml-version))
|
||||
> (lock_dir
|
||||
> (path dune.linux.no-doc.lock)
|
||||
> (solver_env
|
||||
> (arch x86_64)
|
||||
> (os linux)
|
||||
> (os-family ubuntu)
|
||||
> (os-distribution ubuntu)
|
||||
> (os-version 22.04)
|
||||
> (sys-ocaml-version 5.0)))
|
||||
> (lock_dir
|
||||
> (path change-opam-version.lock)
|
||||
> (solver_env
|
||||
> (opam-version 42))
|
||||
> (unset_solver_vars arch os os-distribution os-family os-version sys-ocaml-version))
|
||||
> (context
|
||||
> (default
|
||||
> (name linux)
|
||||
> (lock_dir dune.linux.lock)))
|
||||
> (context
|
||||
> (default
|
||||
> (name no-doc)
|
||||
> (lock_dir dune.linux.no-doc.lock)))
|
||||
> (context
|
||||
> (default
|
||||
> (name change-opam-version)
|
||||
> (lock_dir change-opam-version.lock)))
|
||||
> EOF
|
||||
|
||||
$ dune pkg print-solver-env --all
|
||||
Solver environment for lock directory change-opam-version.lock:
|
||||
- opam-version = 42
|
||||
- post = true
|
||||
- with-dev-setup = false
|
||||
- with-doc = false
|
||||
Solver environment for lock directory dune.linux.lock:
|
||||
- opam-version = 2.2.0~alpha-vendored
|
||||
- os = linux
|
||||
- post = true
|
||||
- with-dev-setup = false
|
||||
- with-doc = false
|
||||
Solver environment for lock directory dune.linux.no-doc.lock:
|
||||
- arch = x86_64
|
||||
- opam-version = 2.2.0~alpha-vendored
|
||||
- os = linux
|
||||
- os-distribution = ubuntu
|
||||
- os-family = ubuntu
|
||||
- os-version = 22.04
|
||||
- post = true
|
||||
- sys-ocaml-version = 5.0
|
||||
- with-dev-setup = false
|
||||
- with-doc = false
|
||||
Solver environment for lock directory dune.lock:
|
||||
- opam-version = 2.2.0~alpha-vendored
|
||||
- post = true
|
||||
- with-dev-setup = false
|
||||
- with-doc = false
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
This test attempts to build a library installed through a lock file and then
|
||||
use it inside dune.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
We set up a library that will be installed as part of the package:
|
||||
|
||||
$ mkdir external_sources
|
||||
$ cat >external_sources/dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package (name mypkg))
|
||||
> EOF
|
||||
$ cat >external_sources/dune <<EOF
|
||||
> (library
|
||||
> (public_name mypkg.lib)
|
||||
> (name test_lib))
|
||||
> EOF
|
||||
$ cat >external_sources/test_lib.ml <<EOF
|
||||
> let x = ()
|
||||
> EOF
|
||||
|
||||
Now we set up a lock file with this package and then attempt to use it:
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> EOF
|
||||
|
||||
$ mkdir dune.lock
|
||||
$ cat >dune.lock/lock.dune <<EOF
|
||||
> (lang package 0.1)
|
||||
> EOF
|
||||
|
||||
$ cat >dune.lock/mypkg.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (source (copy $PWD/external_sources))
|
||||
> (build (run dune build --release --promote-install-file=true . @install))
|
||||
> EOF
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (dirs (:standard \ external_sources))
|
||||
> (library
|
||||
> (name foo)
|
||||
> (libraries mypkg.lib))
|
||||
> EOF
|
||||
|
||||
$ cat >foo.ml <<EOF
|
||||
> let () = Test_lib.x
|
||||
> EOF
|
||||
|
||||
$ dune build foo.cma
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
Dune is defined in the workspace where we're solving
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ mkrepo
|
||||
|
||||
$ mkpkg bar <<EOF
|
||||
> depends: [ "dune" ]
|
||||
> EOF
|
||||
|
||||
$ mkpkg test-dep <<EOF
|
||||
> depends: [ "dune" ]
|
||||
> EOF
|
||||
|
||||
$ solve_project <<EOF
|
||||
> (lang dune 3.19)
|
||||
> (package
|
||||
> (name dune)
|
||||
> (depends (test-dep :with-test)))
|
||||
> (package
|
||||
> (name foo)
|
||||
> (depends bar))
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
- bar.0.0.1
|
||||
- test-dep.0.0.1
|
||||
|
|
@ -0,0 +1 @@
|
|||
bad metadata
|
||||
|
|
@ -0,0 +1 @@
|
|||
opam-version: "2.0"
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
Create a lock directory that didn't originally exist
|
||||
|
||||
$ cat >dune-workspace <<EOF
|
||||
> (lang dune 3.10)
|
||||
> (lock_dir
|
||||
> (repositories mock))
|
||||
> (lock_dir
|
||||
> (path "dev/dune.lock")
|
||||
> (repositories mock))
|
||||
> (repository
|
||||
> (name mock)
|
||||
> (url "file://$(pwd)/mock-opam-repository"))
|
||||
> EOF
|
||||
$ dune pkg lock "dev/dune.lock"
|
||||
Solution for dev/dune.lock:
|
||||
(no dependencies to lock)
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
(no dependencies to lock)
|
||||
$ cat dune.lock/lock.dune
|
||||
(lang package 0.1)
|
||||
|
||||
(repositories
|
||||
(complete false)
|
||||
(used))
|
||||
|
||||
Re-create a lock directory in the newly created lock dir
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
(no dependencies to lock)
|
||||
$ cat dune.lock/lock.dune
|
||||
(lang package 0.1)
|
||||
|
||||
(repositories
|
||||
(complete false)
|
||||
(used))
|
||||
|
||||
Attempt to create a lock directory inside an existing directory without a lock.dune file
|
||||
$ rm -rf dune.lock
|
||||
$ cp -r dir-without-metadata dune.lock
|
||||
$ dune pkg lock
|
||||
Error: Refusing to regenerate lock directory dune.lock
|
||||
Specified lock dir lacks metadata file (lock.dune)
|
||||
[1]
|
||||
|
||||
Attempt to create a lock directory inside an existing directory with an invalid lock.dune file
|
||||
$ rm -rf dune.lock
|
||||
$ cp -r dir-with-invalid-metadata dune.lock
|
||||
$ dune pkg lock
|
||||
Error: Refusing to regenerate lock directory dune.lock
|
||||
Unable to parse lock directory metadata file (dune.lock/lock.dune):
|
||||
File "dune.lock/lock.dune", line 1, characters 0-12:
|
||||
Error: Invalid first line, expected: (lang <lang> <version>)
|
||||
|
||||
[1]
|
||||
|
||||
Attempt to create a lock directory with the same name as an existing regular file
|
||||
$ rm -rf dune.lock
|
||||
$ touch dune.lock
|
||||
$ dune pkg lock
|
||||
Error: Refusing to regenerate lock directory dune.lock
|
||||
Specified lock dir path (dune.lock) is not a directory
|
||||
[1]
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
Test that dune can dynamically select a lockdir with a cond statement
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ mkrepo
|
||||
|
||||
$ mkpkg arm64-only <<EOF
|
||||
> install: [ "echo" "arm64-only" ]
|
||||
> EOF
|
||||
|
||||
$ mkpkg linux-only <<EOF
|
||||
> install: [ "echo" "linux-only" ]
|
||||
> EOF
|
||||
|
||||
$ mkpkg macos-only <<EOF
|
||||
> install: [ "echo" "macos-only" ]
|
||||
> EOF
|
||||
|
||||
$ cat >dune-workspace <<EOF
|
||||
> (lang dune 3.13)
|
||||
> (lock_dir
|
||||
> (path dune.macos.arm64.lock)
|
||||
> (repositories mock)
|
||||
> (solver_env
|
||||
> (arch arm64)
|
||||
> (os macos)))
|
||||
> (lock_dir
|
||||
> (path dune.macos.lock)
|
||||
> (repositories mock)
|
||||
> (solver_env
|
||||
> (arch amd64)
|
||||
> (os macos)))
|
||||
> (lock_dir
|
||||
> (path dune.linux.lock)
|
||||
> (repositories mock)
|
||||
> (solver_env
|
||||
> (arch amd64)
|
||||
> (os linux)))
|
||||
> (lock_dir
|
||||
> (repositories mock))
|
||||
> (repository
|
||||
> (name mock)
|
||||
> (url "file://$(pwd)/mock-opam-repository"))
|
||||
> (context
|
||||
> (default
|
||||
> (lock_dir (cond
|
||||
> ((and
|
||||
> (= %{architecture} arm64)
|
||||
> (= %{system} macosx)) dune.macos.arm64.lock)
|
||||
> ((= %{system} macosx) dune.macos.lock)
|
||||
> ((= %{system} linux) dune.linux.lock)))))
|
||||
> EOF
|
||||
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.13)
|
||||
> (package
|
||||
> (name foo)
|
||||
> (depends
|
||||
> (arm64-only (= :arch arm64))
|
||||
> (macos-only (= :os macos))
|
||||
> (linux-only (= :os linux))))
|
||||
> EOF
|
||||
|
||||
Generate all lockdirs:
|
||||
$ dune pkg lock dune.macos.arm64.lock
|
||||
Solution for dune.macos.arm64.lock:
|
||||
- arm64-only.0.0.1
|
||||
- macos-only.0.0.1
|
||||
$ dune pkg lock dune.macos.lock
|
||||
Solution for dune.macos.lock:
|
||||
- macos-only.0.0.1
|
||||
$ dune pkg lock dune.linux.lock
|
||||
Solution for dune.linux.lock:
|
||||
- linux-only.0.0.1
|
||||
|
||||
Demonstrate that the correct lockdir is being chosen by building packages that
|
||||
are only dependent on on certain systems.
|
||||
|
||||
Build macos package on macos:
|
||||
$ dune clean
|
||||
$ DUNE_CONFIG__OS=macos DUNE_CONFIG__ARCH=arm64 dune build _build/_private/default/.pkg/macos-only/target/
|
||||
macos-only
|
||||
|
||||
Build macos package on macos:
|
||||
$ dune clean
|
||||
$ DUNE_CONFIG__OS=macos DUNE_CONFIG__ARCH=amd64 dune build _build/_private/default/.pkg/macos-only/target/
|
||||
macos-only
|
||||
|
||||
Build linux package on macos (will fail):
|
||||
$ dune clean
|
||||
$ DUNE_CONFIG__OS=macos DUNE_CONFIG__ARCH=amd64 dune build _build/_private/default/.pkg/linux-only/target/
|
||||
Error: Unknown package "linux-only"
|
||||
[1]
|
||||
|
||||
Build macos package on linux (will fail):
|
||||
$ dune clean
|
||||
$ DUNE_CONFIG__OS=linux DUNE_CONFIG__ARCH=amd64 dune build _build/_private/default/.pkg/macos-only/target/
|
||||
Error: Unknown package "macos-only"
|
||||
[1]
|
||||
|
||||
Build linux package on linux:
|
||||
$ dune clean
|
||||
$ DUNE_CONFIG__OS=linux DUNE_CONFIG__ARCH=amd64 dune build _build/_private/default/.pkg/linux-only/target/
|
||||
linux-only
|
||||
|
||||
Try setting the os to one which doesn't have a corresponding lockdir:
|
||||
$ dune clean
|
||||
$ DUNE_CONFIG__OS=windows dune build _build/_private/default/.pkg/linux-only/target/
|
||||
File "dune-workspace", lines 28-32, characters 3-172:
|
||||
28 | ((and
|
||||
29 | (= %{architecture} arm64)
|
||||
30 | (= %{system} macosx)) dune.macos.arm64.lock)
|
||||
31 | ((= %{system} macosx) dune.macos.lock)
|
||||
32 | ((= %{system} linux) dune.linux.lock)))))
|
||||
Error: None of the conditions matched so no lockdir could be chosen.
|
||||
[1]
|
||||
|
||||
Test that cond statements can have a default value:
|
||||
$ cat >dune-workspace <<EOF
|
||||
> (lang dune 3.13)
|
||||
> (lock_dir
|
||||
> (solver_env
|
||||
> (arch amd64)
|
||||
> (os linux))
|
||||
> (repositories mock))
|
||||
> (repository
|
||||
> (name mock)
|
||||
> (url "file://$(pwd)/mock-opam-repository"))
|
||||
> (context
|
||||
> (default
|
||||
> (lock_dir
|
||||
> (cond
|
||||
> (false non-existant)
|
||||
> (default dune.lock)))))
|
||||
> EOF
|
||||
|
||||
$ dune pkg lock dune.lock
|
||||
Solution for dune.lock:
|
||||
- linux-only.0.0.1
|
||||
$ dune clean
|
||||
$ dune build _build/_private/default/.pkg/linux-only/target/
|
||||
linux-only
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
Trying to build a package after updating the dependencies in dune-project but
|
||||
without running `dune pkg lock` must raise an error in the context of Dune
|
||||
Package Managemenet.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
Create a fake project and lock it:
|
||||
|
||||
$ mkrepo
|
||||
$ mkpkg foo <<EOF
|
||||
> build: [ "echo" "foo" ]
|
||||
> EOF
|
||||
$ mkpkg bar <<EOF
|
||||
> build: [ "echo" "bar" ]
|
||||
> EOF
|
||||
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.16)
|
||||
> (package
|
||||
> (name test)
|
||||
> (allow_empty)
|
||||
> (depends foo))
|
||||
> EOF
|
||||
$ add_mock_repo_if_needed
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- foo.0.0.1
|
||||
|
||||
As the lock file is syncronised with `dune-pkg`, the build succeeds:
|
||||
$ build_pkg foo
|
||||
foo
|
||||
|
||||
We add the bar dependency to the test package
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.16)
|
||||
> (package
|
||||
> (name test)
|
||||
> (allow_empty)
|
||||
> (depends foo bar))
|
||||
> EOF
|
||||
|
||||
It fails as we have not regenerated the lock:
|
||||
$ dune build
|
||||
File "dune.lock/lock.dune", line 1, characters 0-0:
|
||||
Error: The lock dir is not sync with your dune-project
|
||||
Hint: run dune pkg lock
|
||||
[1]
|
||||
|
||||
We fix it and the build succeeds again:
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- bar.0.0.1
|
||||
- foo.0.0.1
|
||||
$ build_pkg foo
|
||||
$ build_pkg bar
|
||||
bar
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
Tests that dune can detect when the lockdir has diverged from the local package
|
||||
dependencies due to tampering with the lockdir. These are cases that won't be
|
||||
caught by checking the dependency hash.
|
||||
|
||||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
$ mkpkg a <<EOF
|
||||
> depends: [ "c" "d" ]
|
||||
> EOF
|
||||
$ mkpkg b 0.0.1 <<EOF
|
||||
> EOF
|
||||
$ mkpkg b 0.0.2 <<EOF
|
||||
> EOF
|
||||
$ mkpkg c <<EOF
|
||||
> depends: [ "e" ]
|
||||
> EOF
|
||||
$ mkpkg d <<EOF
|
||||
> EOF
|
||||
$ mkpkg e <<EOF
|
||||
> EOF
|
||||
|
||||
Define some local packages.
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package (name foo) (depends a (b (>= 0.0.2))))
|
||||
> (package (name bar) (depends foo c))
|
||||
> EOF
|
||||
$ add_mock_repo_if_needed
|
||||
|
||||
Without a lockdir this command prints a hint but exits successfully.
|
||||
$ dune pkg validate-lockdir
|
||||
No lockdirs to validate.
|
||||
|
||||
Make the lockdir.
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- a.0.0.1
|
||||
- b.0.0.2
|
||||
- c.0.0.1
|
||||
- d.0.0.1
|
||||
- e.0.0.1
|
||||
|
||||
Initially the lockdir will be valid.
|
||||
$ dune pkg validate-lockdir
|
||||
|
||||
Add a file to the lockdir to cause the parser to fail.
|
||||
$ echo foo > dune.lock/bar.pkg
|
||||
$ dune pkg validate-lockdir
|
||||
Failed to parse lockdir dune.lock:
|
||||
File "dune.lock/bar.pkg", line 1, characters 0-3:
|
||||
Error: S-expression of the form (<name> <values>...) expected
|
||||
|
||||
Error: Some lockdirs do not contain solutions for local packages:
|
||||
- dune.lock
|
||||
[1]
|
||||
|
||||
Remove the file but corrupt the lockdir metadata file.
|
||||
$ rm dune.lock/bar.pkg
|
||||
$ echo foo >> dune.lock/lock.dune
|
||||
$ dune pkg validate-lockdir
|
||||
Failed to parse lockdir dune.lock:
|
||||
File "dune.lock/lock.dune", line 8, characters 0-3:
|
||||
Error: S-expression of the form (<name> <values>...) expected
|
||||
|
||||
Error: Some lockdirs do not contain solutions for local packages:
|
||||
- dune.lock
|
||||
[1]
|
||||
|
||||
Regenerate the lockdir and validate the result.
|
||||
$ rm -r dune.lock
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- a.0.0.1
|
||||
- b.0.0.2
|
||||
- c.0.0.1
|
||||
- d.0.0.1
|
||||
- e.0.0.1
|
||||
$ dune pkg validate-lockdir
|
||||
|
||||
Remove a package from the lockdir.
|
||||
$ rm dune.lock/a.pkg
|
||||
|
||||
This results in an invalid lockdir due to the missing package.
|
||||
$ dune pkg validate-lockdir
|
||||
Lockdir dune.lock does not contain a solution for local packages:
|
||||
File "dune-project", line 2, characters 0-47:
|
||||
Error: The dependencies of local package "foo" could not be satisfied from
|
||||
the lockdir:
|
||||
Package "a" is missing
|
||||
Hint: The lockdir no longer contains a solution for the local packages in
|
||||
this project. Regenerate the lockdir by running: 'dune pkg lock'
|
||||
Error: Some lockdirs do not contain solutions for local packages:
|
||||
- dune.lock
|
||||
[1]
|
||||
|
||||
Regenerate the lockdir and validate the result.
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- a.0.0.1
|
||||
- b.0.0.2
|
||||
- c.0.0.1
|
||||
- d.0.0.1
|
||||
- e.0.0.1
|
||||
$ dune pkg validate-lockdir
|
||||
|
||||
$ cat dune.lock/b.pkg
|
||||
(version 0.0.2)
|
||||
Change the version of a dependency by modifying its lockfile.
|
||||
$ cat >dune.lock/b.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> EOF
|
||||
|
||||
Now the lockdir is invalid as it doesn't contain the right version of "b".
|
||||
$ dune pkg validate-lockdir
|
||||
Lockdir dune.lock does not contain a solution for local packages:
|
||||
File "dune-project", line 2, characters 0-47:
|
||||
Error: The dependencies of local package "foo" could not be satisfied from
|
||||
the lockdir:
|
||||
Found version "0.0.1" of package "b" which doesn't satisfy the required
|
||||
version constraint ">= 0.0.2"
|
||||
Hint: The lockdir no longer contains a solution for the local packages in
|
||||
this project. Regenerate the lockdir by running: 'dune pkg lock'
|
||||
Error: Some lockdirs do not contain solutions for local packages:
|
||||
- dune.lock
|
||||
[1]
|
||||
|
||||
Regenerate the lockdir and validate the result.
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- a.0.0.1
|
||||
- b.0.0.2
|
||||
- c.0.0.1
|
||||
- d.0.0.1
|
||||
- e.0.0.1
|
||||
$ dune pkg validate-lockdir
|
||||
|
||||
Add a package to the lockdir with the same name as a local package.
|
||||
$ cat >dune.lock/foo.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> EOF
|
||||
|
||||
The lockdir is invalid as the package "b" is now defined both locally and in the lockdir.
|
||||
$ dune pkg validate-lockdir
|
||||
Lockdir dune.lock does not contain a solution for local packages:
|
||||
File "dune-project", line 2, characters 0-47:
|
||||
Error: A package named "foo" is defined locally but is also present in the
|
||||
lockdir
|
||||
Hint: The lockdir no longer contains a solution for the local packages in
|
||||
this project. Regenerate the lockdir by running: 'dune pkg lock'
|
||||
Error: Some lockdirs do not contain solutions for local packages:
|
||||
- dune.lock
|
||||
[1]
|
||||
|
||||
Regenerate the lockdir and validate the result.
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- a.0.0.1
|
||||
- b.0.0.2
|
||||
- c.0.0.1
|
||||
- d.0.0.1
|
||||
- e.0.0.1
|
||||
$ dune pkg validate-lockdir
|
||||
|
||||
Add a package to the lockdir which isn't part of the local package dependency hierarchy.
|
||||
$ cat >dune.lock/f.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> EOF
|
||||
|
||||
The lockdir is invalid as it contains unnecessary packages.
|
||||
$ dune pkg validate-lockdir
|
||||
Lockdir dune.lock does not contain a solution for local packages:
|
||||
Error: The lockdir contains packages which are not among the transitive
|
||||
dependencies of any local package:
|
||||
- f.0.0.1
|
||||
Hint: The lockdir no longer contains a solution for the local packages in
|
||||
this project. Regenerate the lockdir by running: 'dune pkg lock'
|
||||
Error: Some lockdirs do not contain solutions for local packages:
|
||||
- dune.lock
|
||||
[1]
|
||||
|
||||
Regenerate the lockdir and validate the result.
|
||||
$ dune pkg lock
|
||||
Solution for dune.lock:
|
||||
- a.0.0.1
|
||||
- b.0.0.2
|
||||
- c.0.0.1
|
||||
- d.0.0.1
|
||||
- e.0.0.1
|
||||
$ dune pkg validate-lockdir
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
Check that if the user tampers with the lockdir in a way that invalidates the
|
||||
package graph then it's caught when loading the lockdir.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
|
||||
$ make_lockdir
|
||||
|
||||
$ cat >dune.lock/a.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (depends b)
|
||||
> EOF
|
||||
$ cat >dune.lock/b.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (depends c)
|
||||
> EOF
|
||||
$ cat >dune.lock/c.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (depends a)
|
||||
> EOF
|
||||
|
||||
$ dune describe pkg lock
|
||||
Contents of dune.lock:
|
||||
- a.0.0.1
|
||||
- b.0.0.1
|
||||
- c.0.0.1
|
||||
|
||||
$ cat >dune.lock/c.pkg <<EOF
|
||||
> (version 0.0.1)
|
||||
> (depends a d)
|
||||
> EOF
|
||||
|
||||
$ dune describe pkg lock
|
||||
File "dune.lock/c.pkg", line 2, characters 11-12:
|
||||
The package "c" depends on the package "d", but "d" does not appear in the
|
||||
lockdir dune.lock.
|
||||
Error: At least one package dependency is itself not present as a package in
|
||||
the lockdir dune.lock.
|
||||
Hint: This could indicate that the lockdir is corrupted. Delete it and then
|
||||
regenerate it by running: 'dune pkg lock'
|
||||
[1]
|
||||
|
||||
$ rm dune.lock/a.pkg
|
||||
|
||||
$ dune describe pkg lock
|
||||
File "dune.lock/c.pkg", line 2, characters 9-10:
|
||||
The package "c" depends on the package "a", but "a" does not appear in the
|
||||
lockdir dune.lock.
|
||||
File "dune.lock/c.pkg", line 2, characters 11-12:
|
||||
The package "c" depends on the package "d", but "d" does not appear in the
|
||||
lockdir dune.lock.
|
||||
Error: At least one package dependency is itself not present as a package in
|
||||
the lockdir dune.lock.
|
||||
Hint: This could indicate that the lockdir is corrupted. Delete it and then
|
||||
regenerate it by running: 'dune pkg lock'
|
||||
[1]
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
When populating the "deps" field of a lockfile, only packages which have locked
|
||||
versions compatible with the lockfile's package's dependency version
|
||||
constraints should be included.
|
||||
|
||||
$ . ./helpers.sh
|
||||
$ mkrepo
|
||||
|
||||
$ mkpkg a 0.0.1
|
||||
$ mkpkg a 0.0.2
|
||||
$ mkpkg b
|
||||
|
||||
The package "c" can be satisfied by b or by a.0.0.1.
|
||||
$ mkpkg c <<EOF
|
||||
> depends: [ "b" | "a" {= "0.0.1"} ]
|
||||
> EOF
|
||||
|
||||
The package "d" can only be satisfied by "a.0.0.2" which will force the package
|
||||
"c" to depend on "b" rather than "a" and ensure "a.0.0.2" is in the solution
|
||||
rather than "a.0.0.1".
|
||||
$ mkpkg d <<EOF
|
||||
> depends: [ "a" {= "0.0.2"} ]
|
||||
> EOF
|
||||
|
||||
$ solve_project <<EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (name foo)
|
||||
> (depends c d))
|
||||
> EOF
|
||||
Solution for dune.lock:
|
||||
- a.0.0.2
|
||||
- b.0.0.1
|
||||
- c.0.0.1
|
||||
- d.0.0.1
|
||||
|
||||
Confirm that we locked "a.0.0.2".
|
||||
$ cat dune.lock/a.pkg
|
||||
(version 0.0.2)
|
||||
|
||||
The deps in the lockfile for "c" shouldn't contain "a" since the only version
|
||||
of "a" that "c" could depend on is "a.0.0.1" which isn't part of the solution.
|
||||
$ cat dune.lock/c.pkg
|
||||
(version 0.0.1)
|
||||
|
||||
(depends b)
|
||||
|
|
@ -0,0 +1 @@
|
|||
opam-version: "2.0"
|
||||
|
|
@ -0,0 +1 @@
|
|||
opam-version: "2.0"
|
||||
|
|
@ -0,0 +1 @@
|
|||
opam-version: "2.0"
|
||||
|
|
@ -0,0 +1 @@
|
|||
opam-version: "2.0"
|
||||
|
|
@ -0,0 +1 @@
|
|||
opam-version: "2.0"
|
||||
|
|
@ -0,0 +1 @@
|
|||
opam-version: "2.0"
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue