Skip to content

o-santi/nix-forall

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

56 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Nix Forall

Nix FFI for all languages. This is a collection of packages built upon a solid interface for interacting with the nix evaluator in Rust, through the recently added Nix C-Api, and a couple of wrapper libraries so that it can be seamlessly accessed from other languages as well.

It is very much in alpha and constantly changing, so don’t expect the API’s to be stable as of now. Still, the general interface for all libraries should stay relatively intact:

  1. Build a nix evaluator instance with given settings, where the default is an empty one. You may pass per-evaluator settings to customize behavior; for instance, like extra-experimental-features="flakes" is needed in order to call builtins.getFlake, used inside state.eval_flake.
  2. Use said nix evaluator to load a nix file, flake or string.
  3. Interact with said nix value.

    If it is a “simple” value, ie. string, number, float, it should translate to a builtin value, while lists, attribute sets and functions will have wrappers around them to implement some niceties, like lazy evaluation by default, special accessors and derivation build() helpers.

Currently, only Rust and Python libraries are defined.

This crate uses nocargo to build directly through nix, without the use of cargo. If you want to use cargo, you may drop in the shell (through nix develop).

nix-for-py/

nix_for_py exposes only one function, nix_evaluator, that is used to instantiate a nix evaluator, that will be used to evaluate nix code:

from nix_for_py import nix_evaluator

evaluator = nix_evaluator(settings={'experimental-features':'flakes'})
nixpkgs = evaluator.eval_flake('github:nixos/nixpkgs')
hello = nixpkgs.legacyPackages['x86_64-linux'].hello.build()
print(hello)

which should print

{'out': '/nix/store/26xbg1ndr7hbcncrlf9nhx5is2b25d13-hello-2.12.1'}

Install

The best way to utilize it is to use it through the overlay exposed by this flake, which will add the nix_for_py package to all python versions of nixpkgs.

pkgs = import nixpkgs {
  overlays = [ nix-forall.overlays.${system}.default ];
};

and then create a python instance with it:

pkgs.mkShell {
  buildInputs = [
    (pkgs.python3.withPackages (p: [ p.nix-for-py ]))
  ];
};

nix-for-rust/

The main way to invoke an evaluator is through the NixSettings builder. It lets you set settings which customize the behavior of the evaluator, and to finalize it, you must give it a store path, which will return the instance of the evaluator.

use nix_for_rust::settings::NixSettings;

pub fn main() -> anyhow::Result<()> {
  let mut state = NixSettings::default()
    .with_setting("experimental-features", "flakes")
    .with_default_store()?;
  let valid_pkgs = state.eval_flake("github:NixOS/nixpkgs")?
    .get("legacyPackages")?
    .get("x86_64-linux")?
    .items()?
    .filter_map(|(_name, term)| term.ok())
    .count();
  println!("Rejoice! You can build {valid_pkgs} packages from nixpkgs.");
  Ok(())
}

About

Nix bindings for all languages

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages