aakropotkin/floco

explain creating pdefs.nix from scratch?

Closed this issue · 2 comments

Caveat: I'm probably not your target user (I'm just looking to build a workflow for obtaining and updating a small number of JS dependencies for the frontend of a non-JS project managed with Nix).

The README suggests we can create pdefs.nix from scratch:

The pdef record closely mirrors the pseudo-standard schema used by most package.json files; but is much stricter about how declarations are written.

If desired, users could ditch package.json files altogether and simply write pdef records for their projects.

I don't have existing json/lock files, so it sounded like the obvious place to start--but I had trouble finding anything else in the docs that clarified the format/affordances. (Aside from just reading existing files.)

Thanks for the question. I can write up a few hand written examples to share. Honestly they're basically the same info you find in package.json but less ambiguous and there's more categories of dependencies for things like testing.

So to declare these "from scratch" the simplest declaration file with a few external dependencies could look something like the block below. Even if you don't have a package-lock.json this will work as long as you have a minimal package.json with at least: { "name": "<NAME>", "version": "<VERSION>" }. For declaring dependencies "manually" there's two approaches, you can either declare depInfo.* records ( a devDependencies / dependencies like record ), or you can write a treeInfo record which is essentially a map of the node_modules/ directory that you want. If I were doing things manually I'd personally use treeInfo.

{
  floco.pdefs = {
    
    # This will automatically get resolved through `registry.npmjs.org'.
    # Without a `fetchInfo' field though, you will need to build with `--impure' 
    lodash."4.17.21" = { ident = "lodash"; version = "4.17.21"; };
    
    # If you want a "pure" run you can add a `fetchInfo' field to a package.
    # You can lookup the `fetchInfo' fields using the script I provided at the bottom.
    # There's easier ways to handle bulk lookups using `nix`, but since you only need a
    # handful the script below won't require you to read any manuals ;)
    acorn."8.8.1" = {
      ident = "acorn";
      version = "8.8.1";
      # defining `binInfo' is optional but provides a small optimization, and is nice for visibility:
      binInfo.binPairs.acorn = "./bin/acorn";
      fetchInfo = {
        narHash = "sha256-W14mU7fhfZajYWDfzRxzSMexNSYKIg63yXSnM/vG0P8=";
        type = "tarball";
        url = "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz";
      };
    };
  
    "<NAME>"."<VERSION>" = {
      ident = "<NAME>";
      version = "<VERSION>";
      ltype = "dir";  # indicates that this is a local project
      fetchInfo.path = ./.;
      treeInfo = {
        "node_modules/lodash".key = "lodash/4.17.21";
        "node_modules/acorn".key = "acorn/8.8.1";
      };    
    };  # End `<NAME>.<VERSION>'
    
  };  # End `pdefs'
}

Dinky shell script to generate fetchInfo records:

$ getFetchInfo() {
>   export url="https://registry.npmjs.org/$1/-/$1-$2.tgz";
>   nix flake prefetch "$url" --json|jq -S '{ type: "tarball", narHash: .hash, url: $ENV.url }'; }
> }

$ getFetchInfo acorn 8.8.1;
{
  "narHash": "sha256-W14mU7fhfZajYWDfzRxzSMexNSYKIg63yXSnM/vG0P8=",
  "type": "tarball",
  "url": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz"
}

Here's a few more examples floating around the source tree. Some of these are generated, but they are small enough to grokk in most cases:

Additionally there's a "reference page"/spec for all of the options. This could definitely use some love in terms of nicer formatting for readability; but it may be useful to you: https://github.com/aakropotkin/floco/wiki/Floco-Packages-Modules#pdefs