Skip to content

feat: user-packages and system-packages batteries#447

Open
charlesfire wants to merge 24 commits intodenful:mainfrom
charlesfire:feature-provides-user-or-system-package
Open

feat: user-packages and system-packages batteries#447
charlesfire wants to merge 24 commits intodenful:mainfrom
charlesfire:feature-provides-user-or-system-package

Conversation

@charlesfire
Copy link
Copy Markdown

@charlesfire charlesfire commented Apr 13, 2026

This is a preliminary implementation of the user-packages and system-packages batteries as suggested in Feature requests braindump.

These new batteries allow the following pattern :

{ den, ... }: {
  den.aspects.games = let
    prismlauncher = (den._.user-packages [ "prismlauncher" ]);
    openrct2 = (den._.user-packages [ "openrct2" ]);
    archipelago = (den._.user-packages [ "archipelago" ]);
  in {
    provides = {
      inherit prismlauncher airshipper openrct2 archipelago;
    };
    includes = [
      prismlauncher
      openrct2
      archipelago
    ];
  };
}

# Somewhere else :
#  den.aspects.tux.includes = [
#    <games/prismlauncher> # Only includes prismlauncher.
#    <games/openrct2> # Only includes openrct2.
#  ];
# Or :
#  den.aspects.tux.includes = [
#    <games> # Includes all games.
#  ];

Potential improvements/alternative api:

  1. Accept either a string or array as input : den._.user-packages "prismlauncher" # also valid : den._.user-packages [ "prismlauncher" "archipelago" ]
  2. Only accept a string as input : den._.user-package "prismlauncher"
  3. Add two more batteries for single package : den._.user-package "prismlauncher" # also valid : den._.user-packages [ "prismlauncher" "archipelago" ]
  4. Somehow figure out a way to merge the functionality of user-packages and system-packages under a single battery : den._.aspect-with-packages [ "prismlauncher" ] # includes prismlauncher in systemPackages when in host-only context and includes prismlauncher in user packages when in user context.
  5. Include support for unfree packages : den._.user-packages [ "discord" ] true # includes discord package and allow unfree discord
  6. Include support for packages from non-default source (i.e. nixos-stable and nixos-unstable, no idea how that could work)

@charlesfire charlesfire changed the title Feat: user-packages and system-packages batteries feat: user-packages and system-packages batteries Apr 13, 2026
@Gwenodai
Copy link
Copy Markdown
Collaborator

Just skimmed this pr so I hope I'm understanding properly. But this battery would allow for the reduction of boilerplate in aspect provides when said provide contains only environment.systemPackages = with pkgs; [...]; or home.packages = with pkgs; [...]; wrapped in den.lib.perHost or den.lib.perUser correct?

Essentially allowing for cutting down boilerplate in simple provides which are currently written like this by removing the following boilerplate at the top of that file:

den.lib.perHost {
    nixos = { pkgs, ... }: {
      environment.systemPackages = with pkgs; [

@charlesfire
Copy link
Copy Markdown
Author

Yes, this is to reduce boilerplate code. When I was rewriting my NixOS config, I noticed I was making a lot of aspects that included a single package because I wanted to keep things modular and I ended up having a lot of almost identical files. This is an attempt at reducing the boilerplate without making things less modular.

@vic
Copy link
Copy Markdown
Member

vic commented Apr 13, 2026

I'm not sure about using strings for package names. We do that on unfree befcause that battry actually is about list of package names nor packages themselves. How about instead of list of strings, having pkgs: [ ... ] function from pkgs to real packages.

Also, we could have a single battery den.provides.pkgs and either it can be context sensitive for all cases, or have provides for each context den.provides.pkgs.to-user , to-home, etc.

@charlesfire
Copy link
Copy Markdown
Author

charlesfire commented Apr 16, 2026

I've reworked the code to provide a single battery pkgs which also provides to-host, to-user and to-home helpers, as per @vic suggestions. However, I couldn't figure out a way to include the helpers as attributes of the pkgs battery (to enable the den._.pkgs.to-host syntax), so if someone knows how to do it, I wouldn't say no to a little help. Also, the battery and the helper functions now take a function returning a list of packages as parameter instead of a list of strings.

The current behavior :

  1. The pkgs battery includes the packages depending on the provided context (as system package in host context and as user/home package in user/home context).
  2. The to-host helper includes a system package in host or user context.
  3. The to-user and the to-home provide a user package based on their respective context.

@charlesfire charlesfire marked this pull request as ready for review April 18, 2026 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants