Refer to a flake from another flake

I have a flake that builds: there’s a file hugo/flake.nix which does the right thing when I do cd hugo && nix build.

Now I want another flake that depends on it. (Concretely, hugo builds my static blog content, and I want a nixops flake that deploys it.)

The obvious attempt, where “obvious” means “fifty blog posts and eight hours later, having written several thousand lines of code and deleted it all again”, is as follows:

{
  description = "my site";
  inputs = {
    nixpkgs.url = "nixpkgs/nixos-unstable";
    hugo.url = "path:./hugo";
  }
  outputs = { self, nixpkgs, hugo, ... }:
    {
      defaultPackage.x86_64-linux = hugo;
    };
}

This, of course, does not work (“flake output attribute ‘defaultPackage.x86_64-linux’ is not a derivation”). For the life of me I don’t know what it is, if it’s not a derivation, because hugo/flake.nix specifies a perfectly good derivation - its outputs is a pkgs.stdenv.mkDerivation and everything.

For completeness, here is an approximation of hugo/flake.nix:

{
  description = "Static site builder for website";

  inputs.flake-utils.url = github:numtide/flake-utils;

  outputs = { self, nixpkgs, flake-utils }:

    flake-utils.lib.eachDefaultSystem (system:
      let pkgs = nixpkgs.legacyPackages.${system}; in
      rec {
        packages = flake-utils.lib.flattenTree {
          gitAndTools = pkgs.gitAndTools;
        };
        defaultPackage =
          pkgs.stdenv.mkDerivation {
            pname = "website";
            version = "0.1.0";

            src = ./contents;

            buildInputs = [
              pkgs.hugo
            ];

            buildPhase = ''
              echo "big pile o' build script"
            '';

            installPhase = ''
              mv output $out
            '';
          };
      });
}

I have two questions:

  1. what is hugo if not a derivation, and how could I have found that out? (nix repl is not helping me in the world of flakes, because I can’t get into a flakey context from the repl.)
  2. how do I get my flake to depend on another flake?

The error doesn’t originate from hugo/flake.nix.

Here, hugo is the flake attribute set, rather than a single derivation. It contains flake outputs (which includes defaultPackage) as well as other meta data. So you should access the default derivation as defaultPackage.x86_64-linux = hugo.defaultPackage.x86_64-linux

By the way, you can examine the flake outputs in the repl:

nix-repl> :lf path:./hugo

Which will define a variable named outputs to the flake outputs. So you can investigate down the output path using the autocompletion by hitting <TAB>.

nix-repl> outputs.<TAB>
nix-repl> outputs.defaultPackage.<TAB>

etc.

Ah, thanks very much - there is clearly some magic going on in flakes, it just turns out that the magic is a little less heavy than I thought. ({ inputs = ...; outputs = foo;} to foo, rather than to foo.defaultPackage.)

I came across this today, while I was looking to do the same thing.

The tip on how to use the repl to inspect the outputs got me hooked up (along with a lot of reading blog posts), thanks.

There’s no working version attached to this thread, so I thought I’d tag an example.

I put together a Flake of building a Rust program (GitHub - asciinema/agg: asciinema gif generator). In the _example directory, I’ve included an example how to call the Flake remotely.

1 Like