jlesquembre / clj-nix

Nix helpers for Clojure projects
https://jlesquembre.github.io/clj-nix/
Eclipse Public License 2.0
139 stars 20 forks source link

Factor mk* tasks into build hooks #69

Open bendlas opened 1 year ago

bendlas commented 1 year ago

Considering that a cljs build has both maven dependencies, as well as npm ones, it would come naturally to express it as a composition of a clj-nix build and an npm build.

When trying to compose these two types of builds, one can find out that buildNpmPackage is built up out of hooks, which makes it considerably easier to massage into the clj build.

But for some projects, it may be far more convenient to be able to add clj-nix via hooks. E.g. for a typical cljs build, you would not use the install hooks of neither build-npm-package nor clj-nix, because often a simple cp target/prod.js $out/www/js/main.js or similar will be sufficient.

This should be possible by roughly following buildNpmPackage's design: https://github.com/NixOS/nixpkgs/tree/master/pkgs/build-support/node/build-npm-package

jlesquembre commented 1 year ago

I like the idea, thanks for the build-npm-package example, I didn't know about pkgs.makeSetupHook

As I understand your suggestion, you'd like to write a derivation with stdenv.mkDerivation, and then consume those hooks via one of the pre*Phases, something like this:

stdenv.mkDerivation {
   preConfigurePhases = [ "cljConfigHook" "npmConfigHook" ];
   buildPhase = "custom build code...";
   # ...
}

Is it correct? If not, could you provide an example of how you'd like to consume those hooks?

bendlas commented 1 year ago

Pretty much correct. Here is my currently working code for building cljs code. Some inline comments, but the overall idea is to combine aspects from buildNpmPackage and mkCljBin:

    packages.hdirect-cljs = pkgs.stdenv.mkDerivation {
      pname = "hdirect-client";
      version = "0-dev";
      src = cleanSrc; ## not sure if cljBuildHook would take `cljProjectSrc` for setting this?
      ## adapted from buildNpmPackage
      npmDeps = pkgs.fetchNpmDeps {
        src = cleanSrc;
        hash = "sha256-sc1nw0mzxoAKXDpRsHOoqYTImKxs68EqVIbLXAVwvWU=";
      };
      npmBuildScript = "release";
      ## Here I can just re-use npm hooks to add the npm aspects to the build
      nativeBuildInputs = with pkgs; with npmHooks.override { inherit nodejs; }; [
        npmConfigHook npmBuildHook
        nodejs clojure
      ];
      ## adapted from mkCljBin.
      ## Ideally, this behavior could added with cljConfigHook to nativeBuildInputs, like the npm hooks
      ## and possibly cljBuildHook (build here is provided by shadow-cljs "release" npm task)
      ## depsCache is re-used from server build
      depsCache = self.packages.${system}.hdirect-clj.deps-cache;
      preBuild = ''
        export HOME="$depsCache"
        export JAVA_TOOL_OPTIONS="-Duser.home=$depsCache"
      '';
    };

EDIT so for the usage example, let's see:

    packages.hdirect-cljs = pkgs.stdenv.mkDerivation {
      pname = "hdirect-client";
      version = "0-dev";
      src = cleanSrc;
      ## adapted from buildNpmPackage
      npmDeps = pkgs.fetchNpmDeps {
        src = cleanSrc;
        hash = "sha256-sc1nw0mzxoAKXDpRsHOoqYTImKxs68EqVIbLXAVwvWU=";
      };
      npmBuildScript = "release";
      ## Here I can just re-use npm hooks to add the npm aspects to the build
      nativeBuildInputs = with pkgs;
                                          with npmHooks.override { inherit nodejs; };
                                          with clj-nix.packages.${system}.cljHooks; [
        npmConfigHook npmBuildHook
        cljConfigHook ## no cljBuildHook, buildPhase provided by npmBuildHook
        nodejs clojure
      ];
      ## since all build hooks share a namespace, more explicit attribute names
      ## are required for hook inputs.
      cljDepsCache = self.packages.${system}.hdirect-clj.deps-cache;
      ## A standalone cljs compile may want to be able to clj-nix.fetchDepsCache
      ## similar to what happens here with npmDeps
    };
jlesquembre commented 1 year ago

@bendlas I started with customJdk, see #79