Defining Components
To define components, there is a set of functions to use and the most flexible (but also lowest
level) is base.mkComponent
. There is also a set of convenience functions to create different types
of components easier. Furthermore, there is also programming language specific versions of the
aforementioned functions.
So, let's declare a simple component. A component usually lives in a sub-folder in the repository so
create a folder example-component
and create a file example-component.nix
in it. In this file,
put the following content:
{ base }:
base.mkComponent {
package = base.mkDerivation {
name = "example-component";
src = ./.;
buildPhase = ''
touch $out/hello-world
'';
};
}
This declares a component with a package
target and uses Nedryland's mkDerivation
which is a wrapper around the standard stdenv.mkDerivation
function but with an added filter
to exclude git-ignored files from the source before building.
.
Exposing your Component
In order for your component to be used, it needs to be added to the build
matrix. This is done by adding it to the call to mkProject
(usually inside
project.nix
). A component is exposed by a call to callFile
followed by optional
arguments. callFile
is part of base
and can therefore be accepted as an argument when declaring
components on a project.
So, something like this:
nedryland.mkProject {
name = "my-project";
components = { callFile } : {
exampleComponent = callFile ./example-component/example-component.nix {};
};
# ...
}
The component will be exposed under the nix attribute exampleComponent
so to build it
you can use nix-build -A exampleComponent.<target>
or nix build .#exampleComponent.<target>
where target
is any target on the component (see
matrix)
Component Dependencies
Nedryland supports components being dependent on other components. This is done by declaring your dependency as an input. This is true for both for packages available in pkgs and your defined components. Add your dependency to the argument list to your file and Nedryland will automatically send it to the function call if available in either components or pkgs.
{ pkgs, base, myDependency }:
base.mkComponent {
# ...
}
Component Types
Nedryland contains a standard set of component types which are described below. Further component types can be added in projects by extending base like explained here.
Services
A service is a component that has no user interface and instead exposes some sort of a remote API. Helpers exists to create gRPC services.
To define a service, your Nix file might look something like:
{ pkgs, base }:
base.mkService {
name = "example-service";
src = ./.;
buildPhase = ''
touch $out/hello-world
'';
};
}
Clients
A client is a component that presents some sort of user interface. It can be either a GUI, a command line interface or something else that a user interacts with (VR experience, etc.).
To define a client, your Nix file might look something like:
{ pkgs, base }:
base.mkClient {
name = "example-client";
src = ./.;
buildPhase = ''
touch $out/hello-world
'';
}
Library
This component type is not exposed directly in base but rather by the different language helpers (see below) and should be used to share common functionality in a library for the language in question.
Documentation
Documentation can be added to a component by the argument docs
, this argument has to
be a set with derivations or metadata. In base.documentation
there are helpers to
create documentation derivations. When building the docs target of the component, a
combination of all the derivation attributes will be created. Any non-derivation will be
serialized to json and stored in metadata.json
in share/doc/<component-name>
.
base.mkComponent {
name = "documented-component";
...
docs = {
user = base.documentation.mkMdbook {
src = ./docs/user;
}
}
}