This commit is contained in:
Amy de Buitléir 2025-10-12 21:48:22 +01:00
parent 25941b723c
commit 0f5e7fb6bc
13 changed files with 630 additions and 120 deletions

View file

@ -0,0 +1,39 @@
{
description = "what does the cow say";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs";
};
outputs = { self, nixpkgs }: {
devShells = {
x86_64-linux.default =
nixpkgs.legacyPackages.x86_64-linux.mkShell {
packages = [
nixpkgs.legacyPackages.x86_64-linux.cowsay
];
}; # mkShell
}; # devShells
packages = {
x86_64-linux.default =
nixpkgs.legacyPackages.x86_64-linux.stdenv.mkDerivation {
name = "cow-hello.sh";
src = ./.;
unpackPhase = "true";
buildPhase = ":";
installPhase =
''
mkdir -p $out/bin
cp $src/cow-hello.sh $out/bin
chmod +x $out/bin/cow-hello.sh
'';
buildInputs = [
nixpkgs.legacyPackages.x86_64-linux.cowsay
];
}; # mkDerivation
}; # packages
}; # outputs
}

View file

@ -1,24 +0,0 @@
{
description = "what does the cow say";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs";
};
outputs = { self, nixpkgs }: {
devShells =
let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
in {
${system}.default =
pkgs.mkShell {
packages = [
pkgs.cowsay
];
}; # mkShell
}; # devShells
};
}

View file

@ -5,46 +5,40 @@
nixpkgs.url = "github:NixOS/nixpkgs";
};
outputs = { self, nixpkgs }: {
outputs = { self, nixpkgs }:
let
devShells =
let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
in {
${system}.default =
pkgs.mkShell {
packages = [
pkgs.cowsay
];
}; # mkShell
}; # devShells
supportedSystems = [ "x86_64-linux" "aarch64-linux" ];
packages =
let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
in rec {
${system}.hello = pkgs.stdenv.mkDerivation {
name = "cow-hello";
forAllSupportedSystems = nixpkgs.lib.genAttrs supportedSystems;
nixpkgsFor = forAllSupportedSystems (system: import nixpkgs { inherit system; });
in {
devShells = forAllSupportedSystems (system:
let pkgs = nixpkgsFor.${system}; in {
default = pkgs.mkShell {
packages = [ pkgs.cowsay ];
};
});
packages = forAllSupportedSystems (system:
let pkgs = nixpkgsFor.${system}; in {
default = pkgs.stdenv.mkDerivation {
name = "cow-hello.sh";
src = ./.;
unpackPhase = "true";
buildPhase = ":";
installPhase =
''
mkdir -p $out/bin
cp $src/cow-hello.sh $out/bin
chmod +x $out/bin/cow-hello.sh
'';
buildInputs = [ pkgs.cowsay ];
};
${system}.default = hello;
}; # mkDerivation
}); # packages
}; # packages
};
}; # outputs
}

View file

@ -55,6 +55,8 @@ as shown later in <<#shebang>>;
then the script would run in any Nix environment.
But for this exercise, we will package it as a "proper" development project.
== Defining the development environment
We want to define the development environment we need for this project,
so that we can recreate it at any time.
Furthermore, anyone else who wants to work on our project will be able to recreate
@ -100,36 +102,13 @@ If we ignore parts of the long package names, the `outputs` section looks like t
This says, in effect, that to create a `default` shell for the `x86_64-linux` architecture,
call the `mkShell` command and tell it you need the `cowsay` package.
We can refactor the code to eliminate some duplication.
[source,nix]
....
devShells = {
x86_64-linux.default =
let
pkgs = nixpkgs.legacyPackages.x86_64-linux;
in
pkgs.mkShell {
packages = [
pkgs.cowsay
];
}; # mkShell
}; # devShells
....
After a bit more refactoring, here's the entire flake.
You may want to compare this carefully to the original version,
in order to reassure yourself that the definitions are equivalent.
////
$ cp ../flake-3.nix flake.nix
////
[source,nix,linenums]
.flake.nix (version 2)
....
$# cat flake.nix
....
The code is rather wordy, with all the _this.that.the.other.thing_ stuff.
Also, the name `legacyPackages` suggests that we're not following current best practices.
(In fact, it could in some circumstances result in duplicate instances of nixpkgs.)
In <<#multi-arch>> we will refactor the code to eliminate some duplication, make it more readable,
and eliminate the references to `legacyPackages`.
For now, we will stick with the ugly, but straightforward, version.
Let's enter the shell.
@ -140,9 +119,10 @@ $# nix develop --command sh
Because we haven't added `flake.nix` to the git repository, it's essentially invisible to Nix.
Let's correct that and try again.
We'll also add the script to the git repository.
....
$ git add flake.nix
$ git add flake.nix cow-hello.sh
$# echo '$ nix develop'
$# nix develop --command sh
....
@ -156,37 +136,153 @@ We can see that `cowsay` is now available, and our script runs.
$ ./cow-hello.sh # Succeeds
....
== Defining the package
We created an appropriate development environment, and tested our script.
Now we are ready to package it.
Add the new lines below to `flake.nix`.
Again, change `x86_64-linux` if needed to match your system architecture.
////
$ cp ../flake-4.nix flake.nix
$ cp ../flake-2.nix flake.nix
////
[source,nix,linenums,highlight="23..48"]
.flake.nix (version 3)
[source,nix,linenums,highlight="19..36"]
.flake.nix (version 2)
....
$# cat flake.nix
....
MAYBE INTRODUCE GETATTRS EARLIER
CONTINUE HERE
CONTINUE HERE
CONTINUE HERE
CONTINUE HERE
Let's test the package.
....
$ nix run
....
If we hadn't added `cow-hello.sh` to the git repository,
we would have an error about the file being missing.
[#multi-arch]
== Supporting multiple architectures
Congratulations!
Our package is popular, and people want to run it on `aarch64-linux` systems.
So now we need to add an entry for that to `packages`.
Of course we want to test it on the new architecture,
so we'll add an entry to `devShells` as well.
////
$ cp ../flake-3.nix flake.nix
////
[source,nix,linenums,highlight="18..23,44..59"]
.flake.nix (version 3)
....
$# cat flake.nix
....
Let's make sure it still runs on our system.
....
$ nix run
....
Of course, we should also test on an `aarch64-linux` system.
But the flake definition is rather long now.
If we need to add even more architectures... ugh.
Even worse, notice that the definitions for `x86_64-linux` are almost identical
to those for `aarch64-linux`.
All that replication makes maintenance more difficult.
What if we make a change to the definition for `aarch64-linux`,
and forget to make the change to `x86_64-linux`?
It's time to refactor the code to eliminate duplication and make it more readable.
In <<#genAttrs>>, I introduced the `lib.genAttrs` function,
and included a promising-looking example.
[source]
.Example
....
nix-repl> lib.genAttrs [ "x86_64-linux" "aarch64-linux" ] (system: "some definitions for ${system}")
{
aarch64-linux = "some definitions for aarch64-linux";
x86_64-linux = "some definitions for x86_64-linux";
}
....
This function generates an attribute set by mapping a function over a list of attribute names.
It takes two arguments.
The first argument is a list; the list elements will become names of values in the resulting attribute set.
The second argument is a function that, given the name of the attribute, returns the attribute's value
In the example, we used a list of system architecture names as the first argument.
For the second argument, we used a function that "pretended" to generate definitions.
What if we wrote a function which, given the name of the system architecture,
would generate the development shell definition for us,
and another function that would do the same for the package definition?
Applying `lib.genAttrs` and the list of system architecture names would give us
all the definitions we need for the outputs section.
The following function will generate a development shell definition.
We will write the definition of `nixpkgsFor.${system}` shortly
[source,nix]
....
system:
let pkgs = nixpkgsFor.${system}; in {
default = pkgs.mkShell {
packages = [ pkgs.cowsay ];
};
}
....
And this one will generate a package definition.
[source,nix]
....
system:
let pkgs = nixpkgsFor.${system}; in {
default = pkgs.stdenv.mkDerivation {
name = "cow-hello.sh";
src = ./.;
unpackPhase = "true";
buildPhase = ":";
installPhase =
''
mkdir -p $out/bin
cp $src/cow-hello.sh $out/bin
chmod +x $out/bin/cow-hello.sh
'';
buildInputs = [ pkgs.cowsay ];
}; # mkDerivation
}
....
////
$ cp ../flake-4.nix flake.nix
////
[source,nix,linenums,highlight="18..23,44..59"]
.flake.nix (version 3)
....
$# cat flake.nix
....
Let's verify that it runs on our system.
....
$ nix run
....
You may want to compare the latest `flake.nix` carefully to the original version,
in order to reassure yourself that the definitions are equivalent.
////
Good adoc0 scripts clean up after themselves.
$ cd .. ; rm -rf my-project # clean up

View file

@ -15,6 +15,142 @@ It takes the following arguments.
d = derivation { name = "myname"; builder = "mybuilder"; system = "mysystem"; }
[source]
.Example
....
nix-repl> d = derivation { name = "myname"; builder = "mybuilder"; system = "mysystem"; }
....
In place of using `derivation`, it is generally more convenient to use
`stdenv.mkDerivation`, which will be be introduced in
<<#mkDerivation>>
== Instantiation vs Realisation
When a derivation is _instantiated_ (_evaluated_),
the Nix expression is parsed and interpreted.
The result is a `.drv` file containing a derivation set.
The package is not built in this step.
// TODO Discuss nix-instantiate or the modern equivalent
The package itself is created when the derivation is _built_ (_realised_).
Any dependencies are also built at this time.
// TODO discuss nix-store -r or the modern equivalent
== Instantiate (evaluate) a derivation
Using the derivation "d" created above...
[source]
.Example
....
nix-repl> d
«derivation /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv»
....
That `.drv` file is plain text; it contains the derivation in a different format.
The mysterious sequence of characters in the filename is a hash of the derivation.
The hash is unique to this derivation.
We could have multiple derivations for a package, perhaps different versions or with different options enabled,
but each one would have a unique hash.
Any changes to the derivation would result in a new hash.
Using the hash, Nix can tell the different derivations apart,
and avoid rebuilding a derivation that has already been built.
We can inspect the derivation in the Nix repl.
[source]
.Example
....
nix-repl> d.drvAttrs
{ builder = "mybuilder"; name = "myname"; system = "mysystem"; }
....
We can examine the `.drv` file.
[source]
.Example
....
$ cat /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv
Derive([("out","/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname","","")],[],[],"mysystem","mybuilder",[],[("builder","mybuilder"),("name","myname"),("out","/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname"),("system","mysystem")])%
....
Or get a nicely formatted version.
[source]
.Example
....
$ nix show-derivation /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv
{
"/nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv": {
"outputs": {
"out": {
"path": "/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname"
}
},
"inputSrcs": [],
"inputDrvs": {},
"system": "mysystem",
"builder": "mybuilder",
"args": [],
"env": {
"builder": "mybuilder",
"name": "myname",
"out": "/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname",
"system": "mysystem"
}
}
}
....
== Find out where the package would be (or was) installed
Using the derivation "d" created above...
[source]
.Example
....
nix-repl> d.outPath
"/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname"
nix-repl> builtins.toString d # also works
"/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname"
....
== Build (realise) a derivation.
In the Nix REPL, using the derivation "d" created above...
[source]
.Example
....
nix-repl> :b d
error: a 'mysystem' with features {} is required to build '/nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv', but I am a 'x86_64-linux' with features {benchmark, big-parallel, kvm, nixos-test}
....
Of course, this example failed to build because the builder and system are fake.
We can achieve the same result at the command line.
[source]
.Example
....
nix-build /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv
this derivation will be built:
/nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv
error: a 'mysystem' with features {} is required to build '/nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv', but I am a 'x86_64-linux' with features {benchmark, big-parallel, kvm, nixos-test}
....
== Remove a derivation
Delete a path from the store *if it is safe to do so* (i.e. if it is
eligible for garbage collection).
[source]
.Example
....
nix-store --delete /nix/store/rc3n0lc4aijyi9wwpmcss7hbxryz6bnh-foo
....
// TODO Contine from this point in ~/github/eolas/nix/nix.md

View file

@ -23,6 +23,12 @@ nix-repl> a.b
12
....
[NOTE]
====
If path supplied to the `import` function is a directory,
the file default.nix in that directory is imported.
====
The scope of the imported file does not inherit the scope of the importer.
[source,nix]
@ -68,3 +74,5 @@ nix-repl> f = import ./c.nix
nix-repl> f 12
19
....
The imported file may import other files, which may in turn import more files.

View file

@ -1,9 +1,15 @@
= Nixpkgs
The Nix Packages collection (nixpkgs) is a large set of Nix expressions containing hundreds of software packages.
The collection includes functions, definitions and other tools provided by Nix for
creating, using, and maintaining Nix packages.
This chapter will explore some of the most useful tools provided by nixpkgs.
In order to use nixpkgs, you must import it.
As discussed in <<#type-path>>, enclosing a path in angle brackets, e.g. <nixpkgs> causes the directories
listed in the environment variable NIX_PATH to be searched for the given
file or directory name.
In the REPL, the command `:l <nixpkgs>` will load `nixpkgs`.
In the REPL, the command `:l <nixpkgs>` will import nixpkgs.
[source]
.Example
@ -12,26 +18,42 @@ nix-repl> :l <nixpkgs>
Added 25694 variables.
....
This gives you access to many more functions and tools.
Alternatively, you can automatically load nixpkgs when you enter the REPL
Alternatively, you can automatically import nixpkgs when you enter the REPL
using the command `nix repl '<nixpkgs>'`.
Within a Nix flake
////
TODO: Add a cross-reference to where we discuss the `lib` functions.
TODO: discuss the `lib` functions
TODO: discuss the `import` directive
TODO: Mention that... In a file, the counterpart to :l <nixpkgs> is with (import <nixpkgs> {}); at the beginning of the file.
////
Within a Nix flake or module, you would use the `import` command.
For example,
== Nixpkgs library function
[source, nix]
....
with (import <nixpkgs> {}); ...
....
In this section, we will look at a few especially useful Nixpkgs library functions.
[NOTE]
====
When you import nixpkgs, you are importing a file, which imports other files, which import still more files.
You can find the location of the nixpkgs directory.
[source]
....
nix-repl> <nixpkgs>
/nix/store/5izw1shpjxb9qhlf67bx427cih5czj8w-source
....
In that directory is a file called `default.nix`, which is what is actually imported.
That file contains an import directive, which triggers more imports, and so on.
As a result, tens of thousands of variables are added to the scope.
Don't worry; this doesn't cause those hundreds of packages to be installed on your system.
It merely gives you access to the recipes for those packages,
plus some tools for working with packages.
====
This chapter will focus on a few especially useful Nixpkgs library functions.
You can find a full list in the
https://nixos.org/manual/nixpkgs/unstable/#sec-functions-library[Nixpkgs manual].
[#genAttrs]
=== `lib.genAttrs`
== `lib.genAttrs`
The function
https://nixos.org/manual/nixpkgs/stable/#function-library-lib.attrsets.genAttrs[`lib.genAttrs`]
@ -40,7 +62,7 @@ It is an alias for `lib.attrsets.genAttrs`.
It takes two arguments:
- names of values in the resulting attribute set
- a function, given the name of the attribute, returns the attribute's value
- a function which, given the name of the attribute, returns the attribute's value
[source]
.Example
@ -55,7 +77,7 @@ nix-repl> lib.genAttrs [ "x86_64-linux" "aarch64-linux" ] (system: "some definit
As we shall see later, this is very useful when writing flakes.
[#getExe]
=== `lib.getExe` and `lib.getExe'`
== `lib.getExe` and `lib.getExe'`
The function
https://nixos.org/manual/nixpkgs/stable/#function-library-lib.meta.getExe[`lib.getExe`]
@ -85,15 +107,102 @@ nix-repl> lib.getExe' pkgs.imagemagick "convert"
"/nix/store/rn6ck85zkpkgdnm00jmn762z22wz86w6-imagemagick-7.1.2-3/bin/convert"
....
[#flakeExposed]
== `lib.systems.flakeExposed`
This attribute is a list of systems that can support flakes.
[source]
.Example
....
nix-repl> lib.systems.flakeExposed
[
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"armv6l-linux"
"armv7l-linux"
"i686-linux"
"aarch64-darwin"
"powerpc64le-linux"
"riscv64-linux"
"x86_64-freebsd"
]
....
[IMPORTANT]
====
This attribute is considered experimental and is subject to change.
====
[#mkShell]
=== `pkgs.mkShell`
== `pkgs.mkShell`
The function
https://nixos.org/manual/nixpkgs/stable/#sec-pkgs-mkShell[`pkgs.mkShell`]
is a wrapper around `stenv.mkDerivation`
defines a Bash environment.
It is a wrapper around `stdenv.mkDerivation`, discussed in <<#mkDerivation>>.
The following attributes are accepted,
along with all attributes of `stdenv.mkDerivation`.
[%autowidth]
|===
|attribute|description|default
|`name`
|the name of the derivation
|`nix-shell`
|`packages`
|executable packages to add the shell
|`[]`
|`inputsFrom`
|build dependencies to add to the shell
|`[]`
|`shellHook`
|Bash statements to be executed by the shell
|`""`
|===
[#flakeExposed]
=== `lib.systems.flakeExposed`
[#mkDerivation]
=== `stdenv.mkDerivation`
== `stdenv.mkDerivation`
The function
https://nixos.org/manual/nixpkgs/stable/#sec-pkgs-mkShell[`pkgs.mkShell`]
is a wrapper around the primitive `derivation` function, discussed in <<#derivations>>.
Some of the commonly used attributes are listed below.
[%autowidth]
|===
|attribute|description
|`pname`
|package name
|`version`
|version number. Use https://semver.org/[semantic versioning], i.e., MAJOR.MINOR.PATCH
|`src`
|location of the source files
|`unpackPhase`
|Bash command to copy/unpack the source files. If set to `"true"`
|`buildPhase`
|Bash commands to build the package. If no action is required, use the no-op `":"` command.
|`installPhase`
|Bash commands to install the package into the Nix store.
|===
Older Nix flakes combined the package name and version number into a single `name` attribute;
however, this is now discouraged.
A complete list of phases is available in the
https://nixos.org/manual/nixpkgs/stable/#sec-stdenv-phases[Nixpkgs manual].
Additional arguments are also listed in the
https://nixos.org/manual/nixpkgs/stable/#ssec-stdenv-attributes[Nixpkgs manual].

View file

@ -46,7 +46,7 @@ Here's a demonstration using the program.
....
$ runghc Main.hs # Fails; dependency not available
$# start-shell nix develop <<EOL
$ runghc Main.hs # Works in development environemnt
$ runghc Main.hs # Works in development environment
$# EOL
....

View file

@ -43,7 +43,7 @@ Here's a demonstration using the program.
....
$ runghc Main.hs # Fails; dependency not available
$# start-shell nix develop <<EOL
$ runghc Main.hs # Works in development environemnt
$ runghc Main.hs # Works in development environment
$# EOL
....

View file

@ -0,0 +1,6 @@
import Data.List.Extra
main :: IO ()
main = do
print $ lower "ABCDE"
print $ upper "XYZ"

View file

@ -0,0 +1,60 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1760298340,
"narHash": "sha256-3oW0TLCtoHw0LMjn3lsGDYc5JlsMK6ScoVtpBXOoWjA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "815f6e9e3ece723a0b0c1593bc78cf980755b9d4",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

View file

@ -0,0 +1,21 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
customGhc = pkgs.haskellPackages.ghcWithPackages (p: with p; [ p.extra ]);
in
{
devShells = rec {
default = pkgs.mkShell {
buildInputs = [ customGhc ];
};
};
}
);
}

View file

@ -1,4 +1,7 @@
personal_ws-1.1 en 0
abc
abcde
aeson
amy
arabic
args
@ -8,7 +11,10 @@ attrs
attrset
attrValues
awk
backend
basePackages
belowfootnote
blahblah
Bloggs
bool
boolean
@ -17,9 +23,12 @@ buildPhase
buildPythonApplication
buildPythonPackage
builtins
Buitleir
bzip
callCabal
cd
cdepillabout
cef
chmod
cmp
codeberg
@ -29,8 +38,8 @@ coreutils
cowsay
cp
currentSystem
customisable
customGhc
customisable
customPython
darwin
deps
@ -38,32 +47,44 @@ depsHostHost
depsTargetTarget
derivationStrict
developPackage
devShell
devShells
didn
diffutils
doesn
drv
drvAttrs
eachDefaultSystem
edolstra
elemAt
env
envrc
errexit
eval
exe
executables
expr
FedericoSchonborn
fetchGit
findutils
findWithDefault
flakeExposed
flakeModule
forAllSupportedSystems
formatName
formatPoint
fourmolu
freebsd
fromList
GC
genAttrs
getAttr
getExe
getFlake
getHostName
ghc
ghci
ghcid
ghcWithPackages
github
GitHub
@ -71,21 +92,36 @@ gitignore
GitLab
GPL
gzip
Hackage
hadn
hasAttr
haskell
Haskell
haskellPackages
haskellProjects
hasn
hayneedlestack
helloNix
hercules
hlsCheck
hostname
HostName
html
imagemagick
init
inputDrvs
inputsFrom
inputSrcs
installables
installPhase
instantiation
isBig
isn
IST
lastModified
lastname
legacyPackages
Lethalman
leveloffset
lf
linenums
@ -94,68 +130,97 @@ linkers
linux
lockfile
lp
Luca
Makefile
md
mkApp
mkDerivation
mkdir
mkApp
mkFlake
mkShell
mybuilder
myname
myPackageName
mysystem
narHash
nixConfig
nixos
NixOS
nixpkgs
nixpkgsFor
Noog
nounset
numtide
outPath
pagkages
pandoc
patchelf
pathExists
pathspec
pdf
perSystem
pipefail
pkgs
Preprocessing
pname
powerpc
preprocessing
prewrap
ps
putStrLn
PWD
py
pygments
pyproject
pythonEnv
readDir
readFile
README
relude
removeAttrs
repl
repo
repos
riscv
runghc
runtimeInputs
sectnums
sed
setuptools
sha
shellHook
smkuehnhold
src
srid
stdenv
stringLength
substring
supercalifragilisticexpialidocious
supportedSystems
svg
tejing
TMP
toc
toclevels
TODO
toJSON
toml
toString
toXML
txt
unpackPhase
untracked
url
usr
utf
utils
variadic
virtualenv
wasn
withBinaryFile
withPackages
writeShellApplication
writeShellScript
writeShellScriptBin
xml
xrefstyle
xyz