-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create a paradigm for multi-application configuration #75
Comments
Open
Solution 1: The actor buys the propIn this solution, the actor moves its config to a folder, so we can have a twig with multiple files. Their structure will look something like this:
The contents of { config, lib, ... }:
let
propExists = config.programs.prop.enabled;
in
{
actor.integrations = lib.mkIf propExists
[
config.programs.prop.package
];
} There are pros and cons to this, which I'll go into later after editing this! |
Solution 1b: the prop has the actor's address written on itTODO: WRITE THIS |
Solution 2: The prop says that it's available via a moduleTODO: WRITE THIS |
Solution 3: The integration is stored at a storage unitTODO: WRITE THIS |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
We've created many paradigms in the lifetime of this project. These include:
default.nix
, which can cause bugsmyLib
to separate real lib functions from our custom oneslib.singleton
to de-nest codehm
alias to easily configure something via home-managerhostVars
for easy access to something that may differ between hostsmkUnfreeNixpkgs
The length of this list, and the number of paradigms I'm probably forgetting, serves as an example of the many problems we have solved. Antipatterns that once seemed impossible to avoid are now no longer a concern.
So, what's the point of all this? The point is that we can solve problems.
And with that, let's get into the problem.
I am the lorax, I speak for the trees
Our configuration attempts to take the stance that most files should be a single actor that isn't load-bearing. What does this mean?
Well, let's think of a NixOS configuration as a tree.
The
flake.nix
is the trunk. It's reasonable to expect that a change to the flake could easily break something. The flake is connected tolimbs
. We can think of the functions inmyLib
as a limb. If we brokemkUnfreeNixpkgs
, we could expect an error elsewhere in the configuration. The same is true for our custom modules. The nature of these files is that they provide functionality to other files, and are thus expected to have a larger impact if they're changed.But, what about leaves? These are the individual files. These leaves can rely on branches. Any file relying on the existence of the
hm
alias, orhostVars
, ormyLib
, or a custom module, But, ideally, they shouldn't rely on each other. A leaf should only expect the tree to remain unchanged. When we encounter a leaf relying on another leaf, it typically means we should create an abstraction within the tree.One of these recent abstractions are
twigs
, or subfolders. Previously, something like configuring Firefox was expected to be limited to a single leaf. But, if Firefox required a lot of configuration, the file's length ended up ballooning out of control. To solve this, we introduced subfolders. Each leaf now represented a single aspect of the Firefox configuration. These leaves are expected to be relatively independent, but they can rely on the existence of another. For anything within the Firefox home-manager module to be configured,hm.programs.firefox.enable
has to be true. The other files can expect that this will be true, and just set things up under this assumption.But, what if two leaves need to be friends?
Leafeo and Leafiet: A love story
Let's use an example. Yazi has a plugin that integrates Starship. We want to enable this plugin, but only on the condition that we're using Starship. If we ever stop using Starship, it should be made clear to the user that we have to disable this integration too.
This integration, like most others, follow a pattern of:
Let's make. From now on, we'll call the program integrating another program the
actor
. The program being integrated will be theprop
. Rewriting our code to accommodate this new terminology:Now, we're set up to go through some hypothetical solutions to this problem,
The text was updated successfully, but these errors were encountered: