Skip to content
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

Add a non-overlay API for defining a config #183

Merged
merged 2 commits into from
Nov 10, 2024
Merged

Add a non-overlay API for defining a config #183

merged 2 commits into from
Nov 10, 2024

Conversation

akirak
Copy link
Member

@akirak akirak commented Oct 6, 2024

This PR adds lib.makeEnv function which is a replacement for the emacsTwist function provided via the overlay. The overlay won't be removed immediately, but it is deprecated.

The rationale for this non-overlay API is to avoid pollution of pkgs and cleaner integration with flake-parts. A recommended usage with flake-parts is as follows:

perSystem = { pkgs, system, emacs-env, ... } = {
  _module.args.emacs-env = inputs.twist.lib.makeEnv {
    # pkgs is required unlike the overlay API
    pkgs = nixpkgs.legacyPackages.${system};
    # The other arguments are the same as emacsTwist
    ...
  };
  packages = {
    inherit emacs-env;
  };
  apps = emacs-env.makeApps { ... };
};

@cmacrae
Copy link
Contributor

cmacrae commented Oct 7, 2024

i've just moved to flake-parts, so i'm very interested in this :) how do you invisage overriding packages with this approach?
to be clear, i'm talking about the current pattern that seems to have emerged:

(final. emacsTwist { }).overrideScope (
  _: prev': {
    elispPackages = prev'.elispPackages.overrideScope (
      prev.callPackage ./package-overrides.nix { inherit (prev') emacs; }
    );
  }
);

@akirak
Copy link
Member Author

akirak commented Oct 8, 2024

how do you invisage overriding packages with this approach?

You can just call overrideScope of the result of the function.

@cmacrae
Copy link
Contributor

cmacrae commented Oct 8, 2024

how do you invisage overriding packages with this approach?

You can just call overrideScope of the result of the function.

Oh... haha, okay, that makes sense - thank you!

I tried taking this for a spin. I'm encountering a strange issue, though.

Here are the relevant parts of my configuration.
(I've also pushed this attempt to a branch here if that's easier).

mkFlake call in flake.nix
flake-parts.lib.mkFlake { inherit inputs; } {
  imports = [ ez-configs.flakeModule ];

  systems = nixpkgs.lib.systems.flakeExposed;

  perSystem = { config, pkgs, system, emacs-env, ... }: {
    _module.args.pkgs = import inputs.nixpkgs {
      inherit system;
      overlays = [
        inputs.emacs-overlay.overlays.emacs
        inputs.org-babel.overlays.default
      ];
      config = { };
    };

    _module.args.emacs-env = import ./configurations/emacs {
      inherit inputs pkgs;
    };

    packages = {
      inherit emacs-env;
    };

    apps = emacs-env.makeApps {
      lockDirName = "configurations/emacs/.lock";
    };
  };

  ezConfigs = {
    globalArgs = {
      inherit inputs;
    };
  } // builtins.listToAttrs (map
    (name: {
      inherit name;
      value = {
        modulesDirectory = ./. + "/modules/${name}";
        configurationsDirectory = ./. + "/configurations/${name}";
      };
    }) [ "home" "darwin" "nixos" ]);
}
configurations/emacs/default.nix Used in the above flake at `_module.args.emacs-env = import ./configurations/emacs ...`
{ inputs, pkgs }:
let
  inherit (pkgs) lib;
  emacsPackage = pkgs.emacs-pgtk;

  treeSitterLoadPath = lib.pipe pkgs.tree-sitter-grammars [
    (lib.filterAttrs (name: _: name != "recurseForDerivations"))
    builtins.attrValues
    (map (drv: {
      # Some grammars don't contain "tree-sitter-" as the prefix,
      # so add it explicitly.
      name = "libtree-sitter-${
          lib.pipe (lib.getName drv) [
            (lib.removeSuffix "-grammar")
            (lib.removePrefix "tree-sitter-")
          ]
        }${pkgs.stdenv.targetPlatform.extensions.sharedLibrary}";
      path = "${drv}/parser";
    }))
    (pkgs.linkFarm "treesit-grammars")
  ];
in

(inputs.twist.lib.makeEnv {
  inherit emacsPackage pkgs;

  lockDir = ./.lock;
  initFiles = [ (pkgs.tangleOrgBabelFile "init.el" ./README.org { }) ];
  inputOverrides = import ./input-overrides.nix { inherit (pkgs) lib; };

  extraSiteStartElisp = ''
    (add-to-list 'treesit-extra-load-path "${treeSitterLoadPath}/")
  '';

  registries = import ./registries.nix {
    inherit inputs;
    emacsSrc = emacsPackage.src;
  };
}).overrideScope (
  _: prev': {
    elispPackages = prev'.elispPackages.overrideScope (
      pkgs.callPackage ./package-overrides.nix { inherit (prev') emacs; }
    );
  }
)

When trying to build my system derivation, I get the following error:

       error: attribute 'lib' missing

       at /nix/store/4asba2q6b8yfrb233gp59g8l5c69gflx-source/pkgs/build-support/default.nix:25:18:

           24|
           25|   elispHelpers = inputs.elisp-helpers.lib.makeLib { inherit lib; };
             |                  ^

Which looks to be this line from twist.nix's build-support package. It's curious how the preceeding line is inherit (pkgs) lib;... which should mean that lib is indeed bound.

I wonder if I'm passing pkgs correctly to makeEnv? I tried passing it as pkgs = nixpkgs.legacyPackages.${system};, however it's the same issue.

Would appreciate any help on this 🙏 But completely understand you're probably very busy with other endeavours :)

@akirak
Copy link
Member Author

akirak commented Oct 8, 2024

@cmacrae elisp-helpers was updated a few days ago. You have to update twist/elisp-helpers input, and it now also needs to be a flake input (changed from a non-flake input). Sorry for the trouble, but this PR is not merged yet.

@cmacrae
Copy link
Contributor

cmacrae commented Oct 8, 2024

You have to update twist/elisp-helpers input, and it now also needs to be a flake input (changed from a non-flake input).

Thank you, that got it working! I'm now no longer using any overlay and have moved to the home-manager module. It took me quite a bit of hacking around, but I understand now how the package loading works, via load-path injection. There's some messing around you have to do if you use use-package to get it to behave.

I'd love to contribute some documentation, though I see that you have some docs in progress and were contemplating a dedicated site. If you're open to the contribution, where would you prefer I record my findings? I feel like I've gained some useful context that could help others enjoy all the fantastic work you've done on this project!

Sorry for the trouble, but this PR is not merged yet.

Absoltutely no need for apologies :) I'm very aware that running code from a PR branch is not a place for expectations of stability

@akirak akirak merged commit 4c568bc into master Nov 10, 2024
2 checks passed
@akirak akirak deleted the non-overlay-api branch November 10, 2024 09:50
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.

2 participants