Skip to content

drupol/pkgs-by-name-for-flake-parts

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Donate!

pkgs-by-name for flake.parts

This project provides a flake.parts module that automatically loads Nix packages from a specified directory via packagesFromDirectoryRecursive. It transforms a directory tree containing package files suitable for callPackage into a corresponding attribute set of derivations that conforms to the Flake standard.

Installation

The structure of the directory containing the packages is the same structure as the pkgs/by-name directory from nixpkgs.

The first step is to add this module as an input to your flake.

  inputs = {
    pkgs-by-name-for-flake-parts.url = "github:drupol/pkgs-by-name-for-flake-parts";
  };

Then, import the module:

  imports = [
    inputs.pkgs-by-name-for-flake-parts.flakeModule
  ];

and configure it:

  perSystem = {
    pkgsDirectory = ./pkgs/by-name;
  };

Optionally, you can consume your "local" packages through the pkgs attribute by using a custom overlay:

  perSystem =
    { system, config, ... }:
    {
      _module.args.pkgs = import inputs.nixpkgs {
        inherit system;
        overlays = [
          (final: prev: {
            local = config.packages;
          })
        ];
      };
      pkgsDirectory = ./pkgs/by-name;
    };

Optionally, you can make the packages publicly accessible through an overlay:

  flake = {
    overlays.default =
      final: prev:
      withSystem prev.stdenv.hostPlatform.system (
        { config, ... }:
        {
          local = config.packages;
        }
      );
  };

Find the complete example below.

flake.nix
{
  inputs = {
    nixpkgs.url = "github:/nixos/nixpkgs/nixos-unstable";
    systems.url = "github:nix-systems/default";
    flake-parts.url = "github:hercules-ci/flake-parts";
    pkgs-by-name-for-flake-parts.url = "github:drupol/pkgs-by-name-for-flake-parts";
  };

  outputs =
    inputs@{ flake-parts, ... }:
    flake-parts.lib.mkFlake { inherit inputs; } (
      { withSystem, ... }:
      {
        systems = import inputs.systems;

        imports = [
          inputs.pkgs-by-name-for-flake-parts.flakeModule
        ];

        perSystem =
          { system, ... }:
          {
            _module.args.pkgs = import inputs.nixpkgs {
              inherit system;
              overlays = [
                inputs.self.overlays.default
              ];
            };
            pkgsDirectory = ./pkgs/by-name;
          };

        flake = {
          overlays.default =
            final: prev:
            withSystem prev.stdenv.hostPlatform.system (
              { config, ... }:
              {
                local = config.packages;
              }
            );
        };
      }
    );
}

Usage

Once the module is configured, it does two things:

  1. It transforms the directory tree of pkgsDirectory into a nested attribute set of derivations via packagesFromDirectoryRecursive. This set is made available as the Flake's legacyPackages attribute. You can read more about the expected folder structure at the link above.
  2. To conform to the Flake standards, this set is then flattened. Each derivation is assigned its path as a name, with the separator being configurable.
  • You can access flake inputs from package files by adding an inputs parameter, it will be automatically populated with a set containing all your inputs.
  • You can access all other packages you have defined in this folder or its subfolders:
    • If it's a top-level package, add its name to your package's parameters.
    • If it's a package in a subfolder, add the top-level folder's name to your package's parameters.

Configuration

This module has the following configuration attributes:

  • pkgsDirectory: The directory containing the packages. This directory should contain a tree of Nix files suitable for callPackage. The default value is null.
  • pkgsNameSeparator: The separator used to concatenate the package name. The default value is /.

Example

Given this flake.nix file:

{
  inputs = {
    flake-parts.url = "github:hercules-ci/flake-parts";
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    pkgs-by-name-for-flake-parts.url = "github:drupol/pkgs-by-name-for-flake-parts";
    # Some non-flake sources for our packages
    example-src = {
      url = "github:ghost/example";
      flake = false;
    };
  };

  outputs = inputs@{ flake-parts, ... }: flake-parts.lib.mkFlake { inherit inputs; } {
    systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" "x86_64-darwin" ];
    imports = [
      inputs.pkgs-by-name-for-flake-parts.flakeModule
    ];
    perSystem = { ... }: {
      pkgsDirectory = ./packages;
    };
  };
}

In this given directory structure, where pkg1 depends on pkg2:

.
├── flake.lock
├── flake.nix
└── packages
    ├── pkg1
    │   └── package.nix
    └── subdirectory
        └── pkg2.nix
# ./packages/pkg1/package.nix
{ stdenv, subdirectory }:
stdenv.mkDerivation {
  name = "pkg1";
  # `subdirectory` contains all packages in the folder `packages/subdirectory`
  buildInputs = [ subdirectory.pkg2 ];
}

pkg2 depends on an input from flake.nix:

# ./packages/subdirectory/pkg2.nix
{ stdenv, inputs }:
stdenv.mkDerivation {
  name = "pkg2";
  src = inputs.example-src;
}

Note how this package does not have its own directory. You can have either <package name>/package.nix, or <package name>.nix. The former is useful if you want to split the package into multiple nix files.

This is the structure of the resulting flake outputs:

outputs
├───legacyPackages
│   ├───aarch64-darwin
│   │   ├───pkg1: package 'pkg1'
│   │   └───subdirectory
│   │       └───pkg2: package 'pkg2'
│   ├───aarch64-linux
│   │   ├───pkg1: package 'pkg1'
│   │   └───subdirectory
│   │       └───pkg2: package 'pkg2'
│   ├───x86_64-darwin
│   │   ├───pkg1: package 'pkg1'
│   │   └───subdirectory
│   │       └───pkg2: package 'pkg2'
│   └───x86_64-linux
│       ├───pkg1: package 'pkg1'
│       └───subdirectory
│           └───pkg2: package 'pkg2'
└───packages
    ├───aarch64-darwin
    │   ├───pkg1: package 'pkg1'
    │   └───"subdirectory/pkg2": package 'pkg2'
    ├───aarch64-linux
    │   ├───pkg1: package 'pkg1'
    │   └───"subdirectory/pkg2": package 'pkg2'
    ├───x86_64-darwin
    │   ├───pkg1: package 'pkg1'
    │   └───"subdirectory/pkg2": package 'pkg2'
    └───x86_64-linux
        ├───pkg1: package 'pkg1'
        └───"subdirectory/pkg2": package 'pkg2'

About

A plugin for flake.parts framework.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

 

Packages

No packages published

Languages