blog/content/posts/nixcon2023/slides/index.html
2023-09-09 01:49:05 -07:00

409 lines
11 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>NixCon 2023 slides</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<link rel="stylesheet" href="node_modules/reveal.js/dist/reset.css" />
<link rel="stylesheet" href="node_modules/reveal.js/dist/reveal.css" />
<link
rel="stylesheet"
href="node_modules/reveal.js/dist/theme/black.css"
/>
<link rel="stylesheet" href="styles.css" />
<link
rel="stylesheet"
href="node_modules/reveal.js/plugin/highlight/monokai.css"
/>
<script type="importmap">
{
"imports": {
"reveal.js": "./node_modules/reveal.js/dist/reveal.esm.js",
"reveal.js/": "./node_modules/reveal.js/",
"reveal.js/plugin/markdown": "./node_modules/reveal.js/plugin/markdown/markdown.esm.js",
"reveal.js/plugin/highlight": "./node_modules/reveal.js/plugin/highlight/highlight.esm.js",
"reveal.js/plugin/notes": "./node_modules/reveal.js/plugin/notes/notes.esm.js"
}
}
</script>
</head>
<body>
<div class="reveal">
<div class="slides">
<section class="title-slide">
<h1>Finding things in nixpkgs and NixOS source</h1>
<div class="meta">
<p>
Jade Lovelace &lt;jade at jade dot fyi&gt;
</p>
<p>
Get the slides at <a href="https://jade.fyi/nixcon2023/slides">https://jade.fyi/nixcon2023/slides</a>
</div>
</section>
<section data-markdown><textarea data-template>
# whoami
* Author of nix-doc (not to be confused with nixdoc)
* Most involved in Nix for Haskell and Rust packaging
* I use NixOS as a dev workstation and server
</textarea>
</section>
<section data-markdown><textarea data-template>
# the sources are for everyone
* We *do* need to improve our documentation
* Nix is uniquely participatory: a *lot* of us write modules and packages, which means reading sources
* Navigating the source is a bit of witchcraft, and there's a lot of it
* With good tooling, the sources of the docs sometimes are faster than the docs
* We should have more interactive docs!
</textarea>
</section>
<section data-markdown><textarea data-template>
# motivation (2.94 million lines of it)
<pre><code class="text"><script type="text/template">
dev/nixpkgs » tokei -t nix .
=======================================
Language Files Lines
=======================================
Nix 30400 2941526
=======================================
Total 30400 2941526
=======================================
</script></code></pre>
</textarea></section>
<section data-markdown><textarea data-template>
# roadmap
* nix
* static analysis
* nixd
* ctags
* dynamic analysis
* using the repl
* using nix-doc
* nixos
* ctags
* repl usage
</textarea>
</section>
<section data-markdown><textarea data-template>
# Static analysis
* Any method that takes 15 seconds or less and doesn't involve running any code
* First way to try:
* Extremely fast
* Objective: "works most of the time"
* I am showing the fancy ways of doing it here
* ripgrep is static analysis too
* Objective of fancy ways: faster and less stuff to sort through
</textarea>
</section>
<section data-markdown><textarea data-template>
# nixd
Newish language server, using Nix as a library. In nixpkgs as `nixd`.
Good for:
* need go-to-definition
* interactive help writing nix code
Limitations:
* does not eval everything
* needs some setup per-project
* imperfect go-to-definition
</textarea>
</section>
<section data-markdown><textarea data-template>
# nixd setup
Install from nixpkgs and configure in your editor. Then:
`.nixd.json`:
<pre><code class="json"><script type="text/template">
{
"eval": {
"target": {
"args": [
"--expr",
"with import ./. {}; nix-doc"
]
}
}
}
</script></code></pre>
</textarea>
</section>
<section class="video" data-markdown><textarea data-template>
# demo (nixd)
<video class="r-stretch" src="./nixd.mp4" controls>
</textarea>
</section>
<section data-markdown><textarea data-template>
# ctags
* Very old and simple source code index format
* Usually gets through abstraction by being too naive to get broken
* Typically generated by simple parse-tree traversal
* Wide editor support ([VSCode extension](https://marketplace.visualstudio.com/items?itemName=jaydenlin.ctags-support); also built into vim/emacs)
Sample:
```text
boot.initrd.luks.reusePassphrases nixos/modules/system/boot/luksroot.nix 533
```
</textarea>
</section>
<section data-markdown><textarea data-template>
# ctags on nix
* `nix-doc tags .` in nixpkgs, then in vim you can `:tj fixedPoints`, `C-]`, etc.
* [WIP ctags for NixOS options (#249243)](https://github.com/NixOS/nixpkgs/pull/249243)
</textarea>
</section>
<section class="video" data-markdown><textarea data-template>
# demo (ctags on nix)
<video class="r-stretch" src="./nix-ctags.mp4" controls>
</textarea>
</section>
<section data-markdown><textarea data-template>
# summary (static analysis)
First try language server, then ctags, then ripgrep.
</textarea>
</section>
<section data-markdown><textarea data-template>
# dynamic analysis
* Static analysis often doesn't cut it, power tools time!
* `nix repl` is your friend
</textarea>
</section>
<section data-markdown><textarea data-template>
# using the repl (nix)
* `nix repl -f .`, `nix repl -f '&lt;nixpkgs&gt;`
* `:lf flake-ref` (more on this later)
* `:e derivation-or-function` to open in editor
</textarea>
</section>
<section data-markdown><textarea data-template>
# getting docs in the repl
<pre><code class="text"><script type="text/template">
nix-repl> :doc builtins.head
Synopsis: builtins.head list
Return the first element of a list; abort evaluation if the argument isnt a list or is
an empty list. You can test whether a list is empty by comparing it with [].
</script></code></pre>
</textarea>
</section>
<section data-markdown><textarea data-template>
# getting docs in the repl (ii)
<pre><code class="text"><script type="text/template">
nix-repl> :doc haskell.lib.overrideSrc
error: value does not have documentation
</script></code></pre>
Oops.
Related:
* [RFC 0145](https://github.com/NixOS/rfcs/pull/145)
* [nix#3904](https://github.com/NixOS/nix/issues/3904)
</textarea>
</section>
<section data-markdown><textarea data-template>
# nix-doc?
<pre><code class="nix"><script type="text/template">
{ pkgs, ... }: {
nix.extraOptions = ''
plugin-files = ${pkgs.nix-doc}/lib/libnix_doc_plugin.so
'';
}
</script></code></pre>
</textarea>
</section>
<section data-markdown><textarea data-template>
# using nix-doc with the repl
<pre><code class="text"><script type="text/template">
nix-repl> builtins.doc haskell.lib.overrideSrc
Override the sources for the package and optionally the version.
This also takes of removing editedCabalFile.
func = drv: src: ...
# /nix/store/wl5m5xfayd69ycyspzyd4rilfgl6wmh0-source/pkgs/development/haskell-modules/lib/default.n
ix:285
null
</script></code></pre>
</textarea>
</section>
<!--
<section data-markdown><textarea data-template>
# `builtins.unsafeGetAttrPos`
Probably the biggest dynamic analysis hammer.
<pre><code class="text"><script type="text/template">
nix-repl> builtins.doc pkgs.fetchFromGitHub
error: value is a set while a lambda was expected
nix-repl> :e pkgs.fetchFromGitHub
error: package 'fetchFromGitHub' has no source location information
nix-repl> builtins.unsafeGetAttrPos "fetchFromGitHub" pkgs
{ column = 3; file = "/nix/store/wl5m5xfayd69ycyspzyd4rilfgl6wmh0-source/pkgs/top-level/all-package
s.nix"; line = 1193; }
</script></code></pre>
</textarea>
</section>
-->
<section class="video" data-markdown><textarea data-template>
<video class="r-stretch" src="./dynamic-demo.mp4" controls>
</textarea>
</section>
<section data-markdown><textarea data-template>
# bonus: using the debugger
* pass `--debugger` to nix
* use `builtins.break (value)` somewhere in the evaluation path
* then use `unsafeGetAttrPos` and others to figure out the source of a value
</textarea>
</section>
<section data-markdown><textarea data-template>
# summary (dynamic analysis)
* `:e function/package`
* \+ works pretty well
* \+ built-in
* \- issues with wrappers (e.g. `fetchFromGitHub`: `lib.makeOverridable`)
* \- doesn't help for attr sets
* `builtins.doc` (nix-doc)
* \+ concise output on functions
* \- issues with wrappers
</textarea>
</section>
<section data-markdown><textarea data-template>
# summary (dynamic analysis)
* `builtins.unsafeGetAttrPos`
* \+ gets close even with abstraction
* \- unergonomic args and return value for interactive use
</textarea>
</section>
<section data-markdown><textarea data-template>
# NixOS ctags ([PR #249243](https://github.com/NixOS/nixpkgs/pull/249243))
With the PR checked out:
<pre><code class="text"><script type="text/template">
$ nix build -f nixos/release.nix optionsCtags -o opts-tags
</script></code></pre>
</textarea>
Then add `opts-tags` to ctags search path (`:set tags+=opts-tags` in vim).
</section>
<section class="video" data-markdown><textarea data-template>
# NixOS ctags (demo)
<video class="r-stretch" src="./nixos-ctags.mp4" controls>
</textarea>
</section>
<section data-markdown><textarea data-template>
# NixOS in the repl
Getting the configuration into the repl:
* Non-flakes: `nix repl -I nixos-config=/path/to/configuration.nix -f &lt;nixpkgs/nixos&gt;`
* Flakes: `nix repl` then `:lf .` then `nixosConfigurations.xx.{....}`
</textarea>
</section>
<section class="video" data-markdown><textarea data-template>
# NixOS in the repl (demo)
<video class="r-stretch" src="./nixos-repl.mp4" controls>
<!--
nix-repl> config.documentation.man.generateCaches
true
nix-repl> options.documentation.man.generateCaches
{ __toString = «lambda @ /nix/store/wl5m5xfayd69ycyspzyd4rilfgl6wmh0-source/lib/modules.nix:807:22»
; _type = "option"; declarations = [ ... ]; default = false; definitions = [ ... ]; definitionsWith
Locations = [ ... ]; description = "Whether to generate the manual page index caches.\nThis allows
searching for a page or\nkeyword using utilities like {manpage}`apropos(1)`\nand the `-k` option of
\n{manpage}`man(1)`.\n"; files = [ ... ]; highestPrio = 1000; isDefined = true; loc = [ ... ]; opti
ons = [ ... ]; type = { ... }; value = true; }
nix-repl> options.documentation.man.generateCaches.definitions
[ true ]
nix-repl> options.documentation.man.generateCaches.definitionsWithLocations
[ { ... } ]
nix-repl> :p options.documentation.man.generateCaches.definitionsWithLocations
[ { file = "/nix/store/wl5m5xfayd69ycyspzyd4rilfgl6wmh0-source/nixos/modules/programs/fish.nix"; va
lue = true; } ]
-->
</textarea>
</section>
<section data-markdown><textarea data-template>
# questions?
slides: https://jade.fyi/nixcon2023
masto: @leftpaddotpy\@hachyderm.io
email: jade at jade dot fyi
code: https://github.com/LF-
github sponsors: https://github.com/sponsors/LF-
</textarea>
</section>
<script type="module" src="main.js"></script>
</body>
</html>