this post was submitted on 31 Aug 2023
5 points (100.0% liked)

nixos

1262 readers
6 users here now

All about NixOS - https://nixos.org/

founded 4 years ago
 

I need to generate a number of scripts in my configuration and make them into a single package (for ease of reference, because there are a lot of them).

So far, I'm creating the scripts via writeShellApplication, making them into packages via an overlay, merging them with buildEnv and then adding the resulting package to `systemPackages.

Something like:

nixpkgs.overlays = [ (final: prev: {
  my-hello-1 = final.writeShellApplication {
    name = "my-hello-1-script";
    text = "echo my hello wolrd 1";
  };
  my-hello-2 = final.writeShellApplication {
    name = "my-hello-2-script";
    text = "echo my hello wolrd 1";
  };
  my-hello-scripts = final.buildEnv {
    name = "my-hello-scripts";
    paths = [ final.my-hello-1 final.my-hello-2 ];
  };
}) ];

environment.systemPackages = [ pkgs.my-hello-scripts ];

This works, but I don't really need the my-hello-1 and my-hello-2 packages... can you think of a way to make do without needing them?

top 7 comments
sorted by: hot top controversial new old
[–] Atemu@lemmy.ml 4 points 1 year ago (1 children)

Why the overlay? If you just want to give the drvs names (good practice IMO), simply use a let binding.

The buildEnv is unnecessary: systemPackages does the same with all the derivations in the list in the end anyways.

[–] gomp@lemmy.ml 2 points 1 year ago* (last edited 1 year ago)

If you just want to give the drvs names [...], simply use a let binding.

I must be missing something here.. my first idea was to put all the writeShellApplications inside systemPackages (with no let bindings: the scripts are generated from config anyway), but it resulted in nixos complaining that it was expecting actual packages.

Edit: scratch that - I was being stupid :)

[–] Klaymore@sh.itjust.works 2 points 1 year ago* (last edited 1 year ago)

There's probably a cleaner way to do this, but you can look at abstractions as a way to reduce all that code repetiton.

[–] ptman@sopuli.xyz 1 points 1 year ago (1 children)

Don't worry about the extra derivations. Nix is full of them.

[–] gomp@lemmy.ml 1 points 1 year ago* (last edited 1 year ago) (1 children)

Well, it does work as-is, and it's not like I'm worried how many symlinks need to be dereerenced... the point is mainly that my nix code could be much simpler if I didn't have to build the overlay attrset like that from a list.

[–] hallettj@beehaw.org 0 points 1 year ago (1 children)

You might simplify it a bit with something like,

let my-hello-scripts = [
  (writeShellApplication {
    name = "my-hello-1-script";
    text = "echo my hello world 1";
  })
  (writeShellApplication {
    name = "my-hello-2-script";
    text = "echo my hello world 2";
  })
];
in
{
  environment.systemPackages = 
    my-hello-scripts ++
    [ pkgs.whatever-else-you-want ];
}
[–] gomp@lemmy.ml 1 points 1 year ago* (last edited 1 year ago)

That was my first idea (well, I say "my"... but it was really suggested by yourself in the question I posted the other day), but it results in nixos complaining that error: A definition for option 'environment.systemPackages."[definition 1-entry 1]"' is not of type 'package'.

It might very well be that I'm doing some stupid mistake here (or maybe it's something that used to work and doesn't anymore?)... here's what I used to test it out:

  environment.systemPackages = [
    pkgs.writeShellApplication {
      name = "some-script";
      text = "echo hello wolrd";
    }
  ];

Edit:

And indeed I was the one doing stupid things: it must be

  environment.systemPackages = [
    (pkgs.writeShellApplication {
      name = "some-script";
      text = "echo hello wolrd";
    })
  ];

with the parentheses, or it's a list with two elements (a function and an attrset)...