Skip to content

migalmoreno/ordenada

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ordenada

Ordenada is a configuration framework based on the Nix package manager that aims to make it easy to build reproducible development environments. It draws inspiration from the RDE project for GNU Guix.

Ordenada’s configuration is centered around users and features. Features are blocks of configuration that provide certain functionality for a user, such as setting up your email, adding your GnuPG keys, or configuring your window manager. Normally, you only need to enable them and all the required settings will automatically be configured for you, although there are many available options you can tweak to fit your needs. See the full list of features and options.

NOTE: Ordenada is in current development and its API is subject to change

Installation

You can install Ordenada into your NixOS configuration using Flakes. First, add its flake URL to your list of inputs.

{
  inputs = {
    # ...other inputs
    ordenada.url = "github:migalmoreno/ordenada";
  };
}

Import its list of modules into your configuration.

{
  outputs =
    { nixpkgs, ordenada, ... }:
    {
      nixosConfigurations."<hostname>" = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        modules = [
          # ...other modules
          ordenada.nixosModules.ordenada
        ];
      };
    };
}

Optionally, if you want to make use of Ordenada’s utility library, to e.g. create your own features, add the following to your configuration.

nixpkgs.overlays = [ ordenada.overlays.default ];

Usage

In a typical single user setup, you just need to add a global set of features and add your user to the users set.

{ config, pkgs, ... }:

{
  ordenada = {
    users = {
      bob = { };
    };
    features = {
      userInfo = {
        username = "bob";
      };
      home.enable = true;
      gnupg.enable = true;
      gtk = {
        enable = true;
        theme = {
          name = "adw-gtk3";
          package = pkgs.adw-gtk3;
        };
      };
      emacs = {
        enable = true;
        all-the-icons.enable = true;
        appearance.enable = true;
        eglot.enable = true;
        modus-themes = {
          enable = true;
          dark = true;
        };
      };
      irc = {
        enable = true;
        accounts = {
          libera = {
            network = "irc.libera.chat";
            nick = "bob";
          };
          oftc = {
            network = "irc.oftc.net";
            nick = "bob";
          };
        };
      };
      mail = {
        enable = true;
        accounts = {
          personal = {
            primary = true;
            fqda = "[email protected]";
            extraConfig = {
              imap = {
                host = "mail.example.com";
                port = 993;
              };
              smtp = {
                host = "mail.example.com";
                port = 465;
              };
            };
          };
        };
      };
      sway.enable = true;
      waybar = {
        enable = true;
        modules = with config.ordenada.features.waybar.defaultModules; [
          swayWorkspaces
          swayWindow
          pulseaudio
          battery
          swayLanguage
          clock
          swaync
        ];
      };
    };
  };
}

In more complex multi-user installations, you can modify the set of user features to match each user’s needs. As shown in the example below, you could make user bob augment the global features with ones specific to him. Alternatively, you could also create a set of user features from scratch and augment certain features as you go, like in the case of the alice user below.

{ config, ... }:

{
  ordenada = {
    users = {
      bob = {
        features = config.ordenada.features // {
          emacs.spelling.enable = true;
          firefox.enable = false;
        };
      };
      alice = {
        features = with config.ordenada.features; {
          userInfo = {
            username = "alice";
          };
          inherit gnupg;
          home.enable = true;
          bash.enable = true;
          emacs = with emacs; {
            enable = true;
            dired.enable = true;
            org-roam.enable = true;
            inherit modus-themes eglot;
          };
        };
      };
    };
    features = {
      userInfo = {
        username = "bob";
      };
      # ...rest of global features
    };
  };
}

With the above setup, two users bob and alice will be configured in the system. bob will end up with an augmented global features setup while alice will only have the features home, bash, the inherited global gnupg feature, and emacs along with its features.

By default, all users inherit the global features. Thus, if you want to write a user features set from scratch (e.g. alice’s example above) you don’t need to include the whole global features set again for a new user feature (e.g. the home, bash, and emacs features above). However, if you want to apply the feature default settings to the user feature (i.e. those that are not explicitly set in the global feature) you’ll need to explicitly inherit from the global feature, such as the case with the gnupg feature above.

Extending it

You can use Ordenada’s utilities to extend its available features with your own. For instance, the following shows how to create a feature example.

{
  config,
  lib,
  pkgs,
  ...
}:

with pkgs.lib.ordenada;

let
  cfg = config.ordenada.features.example;
in
{
  options = {
    ordenada.features.example = {
      enable = lib.mkEnableOption "the example feature";
      message = lib.mkOption {
        type = lib.types.str;
        description = "The message to show.";
        default = "";
      };
    };
  };
  config = (
    lib.mkMerge [
      (lib.mkIf cfg.enable {
        environment.sessionVariables = {
          EXAMPLE_ENV = 1;
        };
      })
      {
        home-manager = mkHomeConfig config "example" (user: {
          home.sessionVariables = lib.mkIf (hasFeature "acme" user) {
            EXAMPLE_HOME_ENV = "EXAMPLE_HOME_ENV_VALUE";
          };
          programs.emacs = mkElispConfig {
            name = "ordenada-example";
            config = ''
              ;; < your Elisp configuration >
              (setq my-elisp-value ${user.features.example.message})
            '';
            elispPackages = [ ];
            summary = "My example Emacs feature";
          };
        });
      }
    ]
  );
}

The example feature above showcases a common feature definition workflow. First, we define a list of options for this feature that we’ll be able to access from anywhere in our configuration. Then, we add a system configuration if the feature is enabled. Next, we add a home configuration via the special utility mkHomeConfig, which allows us to configure home settings for all our Ordenada users. In this example, we set a home environment variable as long as the acme feature is enabled (checked with the hasFeature utility). Finally, we add Emacs Lisp configuration through the mkElispConfig utility which will add a new Emacs configuration package for this feature with interpolated feature options (user.features.example.message).

Configuration Options

See the project’s homepage for the full list of configuration options.

About

A reproducible development environment for Nix

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages