News for hackers. Stuff that matters.
Re:Guix: An advanced operating system by jchw on Tuesday January 15, 2019 @12:27AM (#18909040)
I also started using NixOS around Christmas time. I really love NixOS, but I'm at best lukewarm on Nix as a language. Honestly, though, the language is not my current concern. My current concern is actually more about compartmentalization.

Being able to run `nix-shell -p` and get a shell with a program installed is super cool. Also, being able to add a package to the system declaratively is super cool. However, one thing I wonder about is workflows.

For example, I have a lot of Jetbrains IDEs installed for various languages, but I don't want to pollute my global environment with tools, especially command line tools that pollute the PATH. Let's say I want to use Jetbrains Rider. I can easily start a shell with the dotnet SDK with `nix-shell -p dotnet`, then start Rider under that shell. This is OK, but it feels wrong to me. It feels weird that launching Rider outside of nix-shell won't ever work, yet it's installed globally. And yet, I also kind of want it to be globally installed...

Another solution would be to have Nix expressions for every project I work on. This actually seems better and I've adopted it for a couple projects, but it also irks me because it feels half-baked. I don't know where to put these expressions other than next to the project, but I don't think it belongs in version control. Also, I'm very mixed for what belongs in these environments. Should it be personally suited, with my IDE and developer tools? If I do that, I can't share the same code I'd use for my tooling as I would for my Nixpkg (assuming there is a nixpkg) which leads to a divergence I don't like. (Though maybe that can be solved?)

I almost want a robust system of working environments that encapsulates this. So, I could think about my Nix workflows as separate environments. Declarative or imperative, and ideally with more encapsulation than a typical nix-shell. Maybe instead of orienting my workflow around opening an IDE and opening a project, I can orient it around opening a project environment and then opening an IDE inside of it.

At this point I'm just rambling. I still prefer NixOS for practical reasons, since it makes my complex IOMMU setup a cinch and keeps all of the configuration for it surfaced and documented. But dang, the potential here to shift workflow paradigms is enormous, it feels.

Re:Guix: An advanced operating system by majewsky on Tuesday January 15, 2019 @03:20AM (#18909569)
> I also started using NixOS around Christmas time.

Hah, me too. :)

> I really love NixOS, but I'm at best lukewarm on Nix as a language.

My biggest issue as of now is that the documentation focuses on which individual files you need to touch, but doesn't really explain the big picture. For example, /etc/nixos/configuration.nix contains a function that takes { config, pkgs, ... }. Where do these come from? Where can I find documentation for them? What is in the ellipsis? More generally, where can I find a high-level overview of how the different components interact with each other during, for instance, nixos-rebuild?

Re:Guix: An advanced operating system by sterlind on Tuesday January 15, 2019 @03:53AM (#18909747)
All the quirks are little design patterns that look pretty weird at first, not language features themselves. The resource you're looking for is the Nix Pills series [0]. The LearnXInYMinutes on Nix is also a good overview of the syntax.[1] nix repl is also essential for feeling it out.

To answer your question, { config, pkgs, ... }: declares a function that takes an attribute set containing values for "config" and "pkgs". The ellipsis indicates that it's okay to pass extra attributes.

Nixos-rebuild calls your function by: with (import <nixpkgs> {}); callPackage ./configuration.nix {}

<nixpkgs> is a file containing the set of all symbols (packages are under pkgs, Nix config lives in config, etc.) like a root namespace. callPackage inherits all those symbols and passes them to the function, which is how they got bound.

0. https://nixos.org/nixos/nix-pills/index.html

1. https://learnxinyminutes.com/docs/nix/

EDIT: I guess it's also like Git where it's really confusing until a moment of enlightenment where it all makes sense.

Re:Guix: An advanced operating system by arianvanp on Tuesday January 15, 2019 @09:55AM (#18911477)
NixOS doesn't actually use callPackage. it uses lib.evalModules. The fact there is a difference between how NixOS is evaluated, vs how Nixpkgs is evaluated is something I actually find quite annoying. Whilst nixpkgs is all about functions and dependency injection, NixOS is all about merging dictionaries.

Here is some context, with corresponding criticsm by the person behind Guix, which might give some interesting insights

https://discourse.nixos.org/t/best-resources-for-learning-ab...

Re:Guix: An advanced operating system by fao_ on Tuesday January 15, 2019 @12:41AM (#18909077)
> I don't know where to put these expressions other than next to the project, but I don't think it belongs in version control.

What about using .gitIgnore or using a git submodule for them? Ideally you could have one central repo for nix workflows, and then just have git submodule point to the repo's subfolder, so when you do submodule init, it pulls down that specific folder. Otherwise, you could use .gitignore and a symlink to that as you might do with your dotfiles if you manage those through version control.

Re:Guix: An advanced operating system by jchw on Tuesday January 15, 2019 @12:44AM (#18909085)
Dotfiles are another story. I would prefer my dotfiles to be in source control, but they're not yet, as I haven't gotten to checking out the Nix community's tooling for that, and I prefer to not actually version my whole home folder (at least on machines where my actual work is done in the home folder.)

I think so far my preference might actually be to just have a separate folder, separately versioned, containing my nix expressions for doing work, centrally. But then I kinda want a system for launching into them so I'm not constantly calling nix-shell manually, and that's where I wonder if I actually just want some more tooling for this here.

Re:Guix: An advanced operating system by sterlind on Tuesday January 15, 2019 @01:39AM (#18909245)
I use `git --separate-git-dir=~/.dotfiles --work-tree=~/` and have a .gitignore set to whitelist only things I want to track. This keeps git from colliding with things I have checked out below. I also have configuration.nix import an expression I checked into my $HOME, so I can share common config between all my machines.

For shells, I have a custom `env-python [-p <packageNames>] [-f <extraPaths>]` which brings a fully-configured VS Code (with per-environment config), debuggers and neovim with all the trimmings. Everything inherits in layers so I can add different kinds of environments quite easily.

If you'd like, I can share my dotfiles with you. It's pretty custom but the beauty of Nix is you can clone and run!

Re:Guix: An advanced operating system by asymmetric on Tuesday January 15, 2019 @03:33AM (#18909637)
> I would prefer my dotfiles to be in source control, but they're not yet, as I haven't gotten to checking out the Nix community's tooling for that

Have a look at home manager[0], I use it and have been very happy so far.

[0]: https://github.com/rycee/home-manager

Re:Guix: An advanced operating system by chriswarbo on Tuesday January 15, 2019 @11:33AM (#18912362)
Maybe you'd like `makeWrapper`? It's a little utility which replaces executables with small shell scripts, which set up env vars and PATH components, etc.

I'm not familiar with Jetbrains or dotnet, but you could probably use makeWrapper to make a "jetbrains-with-dotnet" package, something like this:

    with import <nixpkgs> {};
    runCommand "jetbrains-with-dotnet"
      {
        inherit dotnet jetbrains;
        buildInputs = [ makeWrapper ];
      }
      ''
        mkdir "$out/bin"
        makeWrapper "$jetbrains/bin/jetbrains" "$out/bin/jetbrains-with-dotnet" --prefix PATH : "$dotnet/bin"
      ''
This package provides a `jetbrains-with-dotnet` script, which adds the `bin` directory of the `dotnet` package to the start of $PATH then runs the `jetbrains` executable from the `jetbrains` package.

Installing such a package globally will put the `jetbrains-with-dotnet` script in your PATH, but it won't pollute your system with anything from dotnet or jetbrains: those will be downloaded/built and cached in the Nix store, but are only accessible via that script.

Re:Guix: An advanced operating system by Nullabillity on Tuesday January 15, 2019 @02:26AM (#18909390)
> For example, I have a lot of Jetbrains IDEs installed for various languages, but I don't want to pollute my global environment with tools, especially command line tools that pollute the PATH. Let's say I want to use Jetbrains Rider. I can easily start a shell with the dotnet SDK with `nix-shell -p dotnet`, then start Rider under that shell. This is OK, but it feels wrong to me. It feels weird that launching Rider outside of nix-shell won't ever work, yet it's installed globally. And yet, I also kind of want it to be globally installed...

I use nix-buffer[0], which lets Emacs pick up the environment automatically when I open any file in the project. And as long as you only use setq-local it'll stay scoped to those files, "normal" files still open in the regular user environment. It's even seamless to keep files from multiple such projects open at once.

[0]: https://github.com/shlevy/nix-buffer

Re:Guix: An advanced operating system by xfer on Tuesday January 15, 2019 @01:26AM (#18909191)
> This is OK, but it feels wrong to me. It feels weird that launching Rider outside of nix-shell won't ever work, yet it's installed globally.

What do you mean it won't work? I think rider will launch without dotnet, If not then rider dependencies should be fixed to include dotnet. Otherwise, it's the same case for any other distro.

> but I don't think it belongs in version control.

Why not? In fact you should put them in vc since anyone with nix can easily build the program exactly same as on your machine.

> Should it be personally suited, with my IDE and developer tools?

You can create different nix files: e.g. in ide/default.nix you can inherit your default shell.nix and put extra dependency. You may want to skip checking this in vc though.

For a good organization of nix files look at the reflex-frp haskell project.

Re:Guix: An advanced operating system by jchw on Tuesday January 15, 2019 @01:55AM (#18909288)
Rider launches without dotnet, but is not very useful. It becomes effectively a text editor.

Of course, if you wanted to use rider without dotnet, you could. But it doesn't fit my workflow.

And yes, like I said, this is still better than the situation on other distros, but it feels like it's close to being even better than that.

>Why not? In fact you should put them in vc since anyone with nix can easily build the program exactly same as on your machine.

For starters, because I work on a lot of projects that aren't mine. But also, because it's not really standardized.

Like there's a fairly standard practice for putting a package.json in a repository but not really so for default.nix. And it's also not exactly orthogonal to Nixpkgs; if you wanted your project to be in Nixpkgs, your expression would be (slightly) different. That is probably solved by importing the Nixpkg into default.nix, but I haven't tried yet.

Finally, this doesn't capture everything. If I want an environment where I have VSCode with the Go extension installed, I would prefer that to be isolated from other VSCode instances.

That's why I think I want more than just a Nix expression. The tools to do what I want are all here, but the tool to automate the workflow is not.

Re:Guix: An advanced operating system by xfer on Tuesday January 15, 2019 @03:12AM (#18909535)
> If I want an environment where I have VSCode with the Go extension installed, I would prefer that to be isolated from other VSCode instances.

You can absolutely do this by overriding the derivations. The tool to automate your workflow is there(just create a bunch of nix files and a makefile to call nix-shell/nix-build), but not as convenient as you might like.

Re:Guix: An advanced operating system by p_l on Friday January 18, 2019 @12:55AM (#18937316)
Making working per-project definitions in NixOS is what ultimately got me to drop NixOS :(

The specific reason is Ruby + RoR leading to nokogiri... which is something people have been dealing with for several years and there's no solution, and I lost the one file where I managed to get it working good enough to launch rubymine in a way that sees everything necessary.

Similar issues crop in other places, due to how Nix dependencies are handled like unflattened node_modules at times :/

Re:Guix: An advanced operating system by evanrelf on Tuesday January 15, 2019 @01:43AM (#18909260)
Check out `users.users.<name?>.packages` for a declarative way of installing user-specific (non-global) packages.

https://nixos.org/nixos/options.html#users.users+packages

Re:Guix: An advanced operating system by jchw on Tuesday January 15, 2019 @01:57AM (#18909292)
That is cool, but I actually kind of like keeping most things system scoped. What I'd like to do is move everything that is not system scoped into a more granular environment.