Closed brendanzab closed 2 years ago
It's indeed not possible to support pin-depends
reproducibly without an opam lockfile (since it doesn't have any notion of actually pinning the dependency version in the package description). It can probably be supported with --impure
in some way.
For now, you can try passing yocaml as a repo. First, add an input to your flake:
yocaml = {
url = "github:xhtmlboi/yocaml";
flake = false;
};
Then, pass it (together with the default opam-repository) to the buildDuneProject
:
packages.garden = (with opam-nix.lib.${system}; buildDuneProject {
repos = [
(makeOpamRepo yocaml)
opam-nix.inputs.opam-repository
];
} "garden" ocaml-src { }).garden;
opam-nix now supports pin-depends
, but in your particular case it won't work because yocaml
has a non-master
default branch. See https://github.com/NixOS/nix/issues/5139 and https://github.com/NixOS/nix/issues/4456
Oh nice, thanks!
Hmm for some reason the suggestion above doesn't seem to be working for me?
@nix { "action": "setPhase", "phase": "unpackPhase" }
unpacking sources
unpacking source archive /nix/store/l2y5prikdgks7i4a5awc7vkxdxzxi2h9-source-copy
source root is source-copy
@nix { "action": "setPhase", "phase": "patchPhase" }
patching sources
@nix { "action": "setPhase", "phase": "updateAutotoolsGnuConfigScriptsPhase" }
updateAutotoolsGnuConfigScriptsPhase
@nix { "action": "setPhase", "phase": "configurePhase" }
configuring
patching script interpreter paths in .
@nix { "action": "setPhase", "phase": "buildPhase" }
building
File "bin/dune", line 5, characters 55-66:
5 | (libraries preface yocaml yocaml_yaml yocaml_markdown yocaml_unix))
^^^^^^^^^^^
Error: Library "yocaml_unix" not found.
Hint: try:
dune external-lib-deps --missing --no-config --root . --ignore-promoted-rules --default-target @install --always-show-command-line --promote-install-files false --promote-install-files --release --only-packages garden -p garden --profile release -j 10 @install
Ah, yeah, sorry. I forgot to makeOpamRepo
and also opam
doesn't resolve pinned
packages with opam admin list
, so we have to ask for those ourselves:
packages.garden = (with opam-nix.lib.${system};
buildDuneProject {
pinDepends = false;
repos = [ (makeOpamRepo yocaml) opam-nix.inputs.opam-repository ];
} "garden" ocaml-src {
yocaml = null;
yocaml_unix = null;
yocaml_yaml = null;
yocaml_markdown = null;
}).garden;
(Note that you'll also need the latest version of opam-nix since there was an overlay issue)
Wooo, I think that worked! Thanks a bunch. Here's the full flake I made if it's of any use to anyone:
{
description = "Static page generator for my digital garden";
inputs = {
# Utilities for writing flakes
flake-utils.url = github:numtide/flake-utils;
# Precisely filter files copied to the nix store
nix-filter.url = "github:numtide/nix-filter";
# Generate derivations from Dune and OCaml files
opam-nix.url = github:tweag/opam-nix;
# Static site generator for OCaml (not yet published to opam)
yocaml.url = "github:xhtmlboi/yocaml";
yocaml.flake = false;
};
outputs = { self, nixpkgs, flake-utils, nix-filter, opam-nix, yocaml }:
flake-utils.lib.eachDefaultSystem (system:
let
# Legacy packages that have not been converted to flakes
legacyPackages = nixpkgs.legacyPackages.${system};
# OCaml packages available on nixpkgs
ocamlPackages = legacyPackages.ocamlPackages;
# OCaml source files
ocaml-src = nix-filter.lib.filter {
root = ./.;
include = [
"dune-project"
"garden.opam.template"
(nix-filter.lib.inDirectory "bin")
];
};
in
{
# Executed by `nix build .#<name>`
packages.garden =
(opam-nix.lib.${system}.buildDuneProject
{
pinDepends = false;
repos = [
(opam-nix.lib.${system}.makeOpamRepo yocaml)
opam-nix.inputs.opam-repository
];
}
"garden"
ocaml-src
{
yocaml = null;
yocaml_unix = null;
yocaml_yaml = null;
yocaml_markdown = null;
}).garden;
# Executed by `nix build`
defaultPackage = self.packages.${system}.garden;
# Executed by `nix run .#<name>`
apps.garden = {
type = "app";
program = "${self.packages.${system}.garden}/bin/garden";
};
# Executed by `nix run`
defaultApp = self.apps.${system}.garden;
# Used by `nix develop`
devShell = legacyPackages.mkShell {
nativeBuildInputs = [
# Editor support
legacyPackages.fswatch # for `dune build --watch --terminal-persistence=clear-on-rebuild`
# legacyPackages.ocamlformat # FIXME: fails to build `uunf` on aarch64-darwin :(
ocamlPackages.merlin
ocamlPackages.ocaml-lsp
];
inputsFrom = [
self.defaultPackage.${system}
];
};
});
}
Ahh wierd, for some reason when I do dune build --watch --terminal-persistence=clear-on-rebuild
using the above nix file, builds a bin/garden.exe
, rather than putting it in the _build
directory?
Ahh wait, I think that must be because of the recommended dune
file:
(executable
(name garden)
(public_name garden)
(promote (until-clean)) ; <-- this is the culprit!
(libraries preface yocaml yocaml_yaml yocaml_markdown yocaml_unix))
Thanks to work of @rizo now non-master main branches are also supported! E.g. this works: https://github.com/tweag/opam-nix/blob/main/examples/readme/my-package/my-package.opam#L16
Should I be looking at https://github.com/tweag/opam-nix#examples-8 for this?
No, it should just work with buildOpamProject
and buildDuneProject
now.
So I switched on pinDepends = true
:
but now I am getting warnings like:
trace: warning: pin-depends without an explicit sha1 is not supported in pure evaluation mode; try with --impure
I also get a build error:
@nix { "action": "setPhase", "phase": "unpackPhase" }
unpacking sources
unpacking source archive /nix/store/4d0ix5djms3n2jnjdc58l916cwack1rp-empty-directory
source root is empty-directory
@nix { "action": "setPhase", "phase": "patchPhase" }
patching sources
@nix { "action": "setPhase", "phase": "updateAutotoolsGnuConfigScriptsPhase" }
updateAutotoolsGnuConfigScriptsPhase
@nix { "action": "setPhase", "phase": "configurePhase" }
configuring
patching script interpreter paths in .
cp: cannot create regular file '/tmp/opam-subst': Permission denied
Oh, so I need to set a sha in .opam.template
? (sorry, I was expecting it to be ok, given I had supplied the flake input)
I'm wondering if it's possible to use an opam lockfile to simplify this kind of thing? This is what naersk does, but I'm not too clear on the specifics of how opam works to know if it's possible here too… eg. I'm not sure how to generate the lockfile in the first place. I'm guessing it might require opam to be installed globally?
but now I am getting warnings like:
Well, the warning tells you exactly what to do: run your command again with --impure
, or set the git commit sha1 (a.k.a rev) in the opam file (like done in the example: https://github.com/tweag/opam-nix/blob/main/examples/readme/my-package/my-package.opam#L14). To be clear, this is also supported by opam, and is a good idea for reproducibility purposes regardless of opam-nix.
I also get a build error:
That error looks weird, I'll look into it
Well, the warning tells you exactly what to do
Yeah, I didn't want to run it in --impure
, as I thought this was the point of flakes: offering isolation. I also couldn't tell from the warning where to set the sha - I was looking for somewhere in the nix
file, not the .opam.template
.
To be clear, this is also supported by opam, and is a good idea for reproducibility purposes regardless of opam-nix.
Ahh yeah, this might be me confused by opam's model… (which I find confoundingly frustrating at the best of times). Coming from Cargo git dependencies are automatically pinned in a lockfile - ie. the 'correct way' is enabled by default. I'll go ahead and add the sha to the pin-depends
URLs, but it is kind of frustrating as it loses information on what branch it is supposed to be tracking, and can't be updated with tooling. :(
Sorry again for all my confusion!
Could it be that there is some weirdness in how opam-nix
is understanding my pinned deps?
pin-depends: [
# The sha1 hashes currently point to the main branch of the yocaml repository
["yocaml.dev" "git+https://github.com/xhtmlboi/yocaml.git#167cddf111bec1095fc35a10f5c10d2d25e9adbd"]
["yocaml_markdown.dev" "git+https://github.com/xhtmlboi/yocaml.git#167cddf111bec1095fc35a10f5c10d2d25e9adbd"]
["yocaml_mustache.dev" "git+https://github.com/xhtmlboi/yocaml.git#167cddf111bec1095fc35a10f5c10d2d25e9adbd"]
["yocaml_unix.dev" "git+https://github.com/xhtmlboi/yocaml.git#167cddf111bec1095fc35a10f5c10d2d25e9adbd"]
["yocaml_yaml.dev" "git+https://github.com/xhtmlboi/yocaml.git#167cddf111bec1095fc35a10f5c10d2d25e9adbd"]
]
Certainly possible :)
What is the exact problem you're experiencing?
I've just checked and that snippet does what I would expect. Are you on latest opam-nix?
Describe the bug Opam-nix seems not to look for
pin-depends
.I've been trying to experiment with
yocaml
. It seems not to have been published to opam yet, and people seem to be usingpin-depends
as a way to use it in their projects?I searched on the
opam-nix
repo and it seems likepin-depends
is not mentioned, so maybe it is not yet supported? I understand that it might be tricky to do this while maintaining reproducibility however? So I'm not sure what that would look like.To Reproduce
flake.nix
dune-project
bin/dune
bin/garden.ml
garden.opam.template
After running
nix build
I get:nix log ...-garden-local.drv
The generated opam file is:
/nix/store/...-source-copy/garden.opam
Expected behavior
The build should find the dependencies
Environment
Version of the code:
Additional context Add any other context about the problem here.