···11# Unsurprising
22+33+# Lecture
44+55+- The Purely Functional Software Deployment Model
66+- https://jonathanlorimer.dev/posts/nix-thesis.html
+67
examples/flake.rs
···11+use pkgs;
22+// use pkgs::prelude::*;
33+44+use gitignore;
55+// not from pkgs, as more specialized
66+use rust as rust_external;
77+88+// formatter already exist by default
99+1010+let packages = {
1111+ let lspelling: Drv = /* import lspelling package */; // { inherit gitignore; };
1212+1313+ Packages::new_default(lspelling, { lspelling })
1414+}
1515+1616+let apps = {
1717+ let lspelling = super::packages::lspelling::build().bin.lspelling;
1818+1919+ Packages::new_default(lspelling, { lspelling })
2020+}
2121+2222+let shells: std::???::Shells = {
2323+ let rust_toolchain: Drv = rust_external::from_rustup_toolchain_file("./rust-toolchain.toml");
2424+ // shadowing :eyes:
2525+ let rust_toolchain: Drv = rust_toolchain.override({ extensions: [ "rust-analyzer" ]; });
2626+ // -- other, cleaner imo, way
2727+ let rust_toolchain: Drv = rust_external::from_rustup_toolchain_file("./rust-toolchain.toml", /* to_add: */ _ { extensions: [ "rust-analyzer" ] });
2828+2929+ let dev = Shell::new {
3030+ host_packages: [
3131+ // with pkgs; ???
3232+ pkgs::pkg_config,
3333+ rust_toolchain,
3434+ pkgs::act,
3535+3636+ pkgs::cargo_workspaces,
3737+ ],
3838+ target_packages: [
3939+ pkgs::hunspell,
4040+ pkgs::libclang,
4141+ pkgs::cc // stdenv.cc.cc
4242+ ],
4343+4444+ env: {
4545+ RUST_SRC_PATH: rust_toolchain.rust_lib_source as Str,
4646+ LD_LIBRARY_PATH: makeLibraryPath buildInputs,
4747+4848+ RUST_LOG: "lspelling_lsp=debug,lspelling_wordc=debug,debug",
4949+ LOG_FILE: "/tmp/lspelling.log",
5050+5151+ HUNSPELL_DICT: "${pkgs::hunspell_dicts::en_us_large.build()}/share/hunspell/en_US",
5252+ } as Map<Str, impl ToString | Arr<impl ToString>>,
5353+ // } as Map<Str, impl ToString>,
5454+ };
5555+5656+ Shells::new({ dev })
5757+}
5858+5959+// Flake::new(_ {
6060+ // packages: { lspelling: lspelling_pkgs },
6161+ // packages: { lspelling: pkgs::lspelling },
6262+ // apps, // same
6363+ // shells: { dev: dev_shell },
6464+// })
6565+6666+// this is returned
6767+Flake::new(_ { packages, apps, shells })
+48
examples/lib.rs
···11+// # Ressources
22+// https://github.com/NixOS/nixpkgs/blob/master/doc/stdenv/stdenv.chapter.md
33+// ---
44+55+//! In separate crates/projects
66+77+/// tools for transforming data, building derivations
88+mod std/core {
99+ // lib, build, install, etc.
1010+1111+ mod derivation {
1212+ // e.g. X is lspelling
1313+ struct Drv<X> {
1414+ meta: DrvMeta,
1515+ source: Src,
1616+ build_plan: BuildPlan,
1717+1818+ more: X,
1919+ }
2020+ }
2121+2222+ mod build {
2323+ let unpack = BuildStep(|| {
2424+ let src: PathBuf = std::build::source();
2525+2626+ // unpack in cwd
2727+ match src.ext() {
2828+ ".tar.gz" | ".tgz" | ".tar.Z" => gzip(src),
2929+ ".tar.bz2" | ".tbz2" | ".tbz" => bzip2(src),
3030+ ".tar.xz" | ".tar.lzma" | ".txz" => xz(src),
3131+ _ => panic!("could not unpack")
3232+ }
3333+ });
3434+ }
3535+}
3636+3737+/// all package derivations
3838+mod pkgs {
3939+ mod hello;
4040+ mod libxkbcommon;
4141+ mod sway;
4242+}
4343+4444+/// options definitions
4545+mod options {
4646+ mod machine { }
4747+ mod user { }
4848+}
+69
examples/pkgs/hello.rs
···11+use std::derivation::{Derivation, DerivationMeta, BuildStep, Source};
22+33+pub let meta = DerivationMeta.new {
44+ name: "hello",
55+ version: "2.12.1",
66+ description: "Program that produces a familiar, friendly greeting",
77+88+ license: License::Gpl3Plus | License::Apache,
99+1010+ // changelog, mainteners, platforms, etc.
1111+ // `mainProgram` makes no sense
1212+};
1313+1414+let source = Source::fetch_url(_ {
1515+ // interpolation vvvvvvvvvvvv
1616+ url: "mirror://gnu/hello/hello-{meta.version}.tar.gz",
1717+ // keep hash in source?
1818+ hash: "sha256-jZkUKv2SV28wsM18tCqNxoCZmLxdYH2Idh9RLibH2yA=",
1919+});
2020+2121+// none
2222+let build_step = BuildStep::new(|| {
2323+ // call `./configure`
2424+ std::build::???::configure();
2525+ // call `make`
2626+ std::build::make::???();
2727+});
2828+2929+// special imperative block to act
3030+let install_step = BuildStep::new(|| {
3131+ // type is opt, just to show here
3232+ let out: PathBuf = std::build::request_output_dir();
3333+3434+ std::install::make::install();
3535+});
3636+3737+// special imperative block to act
3838+let install_check = BuildStep::new(|| {
3939+ let out: PathBuf = std::build::request_output_dir();
4040+ let hello_bin = out.join("bin/hello");
4141+4242+ std::check::is_present(hello_bin)?;
4343+4444+ std::check::exec(hello_bin, []);
4545+});
4646+4747+// ability to document derivations
4848+pub let derivation = Derivation::new(_ {
4949+ meta,
5050+ source,
5151+5252+ // new starts from empty plan, could have `unpack` with first being unpack phase, `stdenv` for configure make make install workflows
5353+ steps: BuildPlan::new([
5454+ // see example down below
5555+ std::build::unpack(),
5656+ // patch step
5757+ // configure step
5858+ build_step,
5959+ // build check step
6060+ install_step,
6161+ // fixup step, patches files to work in nix??? envs
6262+ install_check, // could do some `bin/<name> -v` to ensure that linking worked fine
6363+ // distribution step
6464+ ]),
6565+});
6666+6767+let out = derivation.out();
6868+6969+pub let bin = out.join()