You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Description: is a string describing the flake.
- Inputs: is an attribute set of all the dependencies of the flake. The schema is described below.
- Outputs: is a function of one argument that takes an attribute set of all the realized inputs, and outputs another attribute set which schema is described below.
- NixConfig: is an attribute set of values which reflect the values given to nix.conf. This can extend the normal behavior of a user's nix experience by adding flake-specific configuration, such as a binary cache.
The biggest deviation for our flake is:
- CellsFrom: The cells that make up our organism must be defined in a single folder within our repository. It's idiomatic to name this folder either cells or nix. Within this directory, each cell is isolated into a subdirectory, with all of its cell blocks further nested under this subdirectory.
- CellBlock: Each cell consists of one or more blocks which are defined here in list form. Recall that cell blocks are typed, and the general format for defining them is (std.blockTypes.<type> "<name>"); where <type> is a valid block type as defined here and <name> is where std should look for the cell block under the parent cell's folder.
Keep in mind:
# This cell block is used to define how our example application is built.
# Ultimately, this means it produces a nix derivation that, when evalulated,
# produces our binary.
This is very important structure, this allows all cell blocks to access all inputs and even cell blocks from sibling cells:
NOTE: Since derivations are hashed based on their inputs, limiting inputs is the best practice to maximize cache usage and avoid the unnecessary rebuilding of our binary.
BIG LESSON, only one flake per repo, no idea why this is not a huge first intro to this. I could not get this last part to run https://jmgilman.github.io/std-book/getting_started/growing.html but after a day of struggle finally understand flake.nix is a map of your repo that you update and use to call.
I resolved the above by limiting the scope of the repo simply to the rust directory customizing it for my use case
This now works in my “new” repo, if you do not do this your git working tree places artifacts in the wrong place in the store
nix run .#default world
Lets start a shell with std enabled (note we can add this devshell to our flake but in this case we manually run:
nix shell github:divnix/std
I can now get to the TUI menu with
std
I can see available commands in my TUI with
std list
Returns:
//example/apps/default:build -- 💡 An example Rust binary which greets the user: build it
//example/apps/default:run -- 💡 An example Rust binary which greets the user: run it
The above is expected as the program wants an input <name>, lets try it with:
std //example/apps/default:run Berno
Returns:
Hello, Berno!
The amazing think to note is that our flake.nix is a map of all the relevant parts of the repo we can use to define how we call everything in the repo
- Inputs can be accessed via inputs
- Anything within our local cell can be accessed via cell
- Other cells can be accessed via inputs.cells
Lets work a bit further on how we add things to our environments using devshell
As we begin iterating on our project, we’ll come across this common theme: to add new functionality to our project, simply add new cell blocks. In the case of devshell, this remains true: to begin, we’ll add a new block to our flake.nix:
{
inputs.std.url = "github:divnix/std";
inputs.nixpkgs.url = "nixpkgs";
inputs.rust-overlay.url = "github:oxalica/rust-overlay";
outputs = { std, ... } @ inputs:
std.growOn
{
inherit inputs;
cellsFrom = ./nix;
cellBlocks = [
(std.blockTypes.runnables "apps")
# The `devshell` type will allow us to have "development shells"
# available. These are managed by `numtide/devshell`.
# See: https://github.com/numtide/devshell
(std.blockTypes.devshells "devshells")
# The `function` type is a generic block type that allows us to define
# some common Nix code that can be used in other cells. In this case,
# we're defining a toolchain cell block that will contain derivations
# for the Rust toolchain.
(std.blockTypes.functions "toolchain")
];
}
{
packages = std.harvest inputs.self [ "example" "apps" ];
# We want to export our development shells so that the following works
# as expected:
#
# > nix develop
#
# Or, we can put the following in a .envrc:
#
# use flake
devShells = std.harvest inputs.self [ "example" "devshells" ];
};
}
Notice we added 2 things devshells and a toolchain, both will be placed in my examples directory
If you’re not familiar with the idea of a development shell, it’s essentially a self-contained environment that can be configured to provide all the tools and dependencies needed to work on our project.
Ok to be able to take advantage of the devshells lets install direnv
sudo apt-get install direnv
Lets make sure direnv is running by adding the following to .bashrc
eval "$(direnv hook $SHELL)"
Reload bashrc
Now lets go add a .envrc to launch the devshell when we get into our directory
#! /bin/sh
# This file is sourced by direnv when entering the directory. The content below
# is pulled from: https://divnix.github.io/std/guides/envrc.html
source_up_if_exists .envrc.local
export DEVSHELL_TARGET=${DEVSHELL_TARGET:-dev}
. "$(nix eval .#__std.direnv_lib)"
use std nix "//example/devshells:${DEVSHELL_TARGET}
Lets allow direnv to run this .envrc
direnv allow .
Aite lets get out of the directory and see what we see
I see in the shell my variables got loaded lets see what std show us
std list
Yas:
//example/apps/default:build -- 💡 An example Rust binary which greets the user: build it
//example/apps/default:run -- 💡 An example Rust binary which greets the user: run it
//example/devshells/dev:build -- 💡 General development shell with default yumi environment.: build it
//example/devshells/dev:enter -- 💡 General development shell with default yumi environment.: enter this devshell
Lets run our program again, notice std is now avaialbe to us because we are already in our environment
std //example/apps/default:run joy
And we get our expected output
Hello, joy!
Ok so we now have a very basic flake, if we go into the directory we immediatly have access to all the variables needed to execute