Skip to content

Instantly share code, notes, and snippets.

@Profpatsch
Last active June 7, 2019 17:08
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Profpatsch/d5c8e1ccd68baab0e3f0 to your computer and use it in GitHub Desktop.
Save Profpatsch/d5c8e1ccd68baab0e3f0 to your computer and use it in GitHub Desktop.
Nix UI notes & proposals concerning https://gist.github.com/edolstra/efcadfd240c2d8906348

General

Search paths & namepaces

NIX_PATH only of the form: nixpkgs=https://nixos.org…:mypkgs=/home/bar/nixpkgs

then: nix install nixpkgs.pkgs.hello

and nix install mypkgs.pkgs.hello

Alternatively it should be possible to specify the general namespaces of nix install, maybe:

# ~/.config/nix/namepspaces.nix:
{ config, ... }:
{
  nix.namespaces.p = nix.namespaces.nixpkgs.pkgs;
}

and now: nix install p.hello

nix will create its own namespace module from NIX_PATH first. The above would create:

# internal nix namepace module
{ config, ... }:
{
  nix.namespaces = {
    nixpkgs = https://nixos.org;
    mypkgs = /home/bar/nixpkgs;
  };
}

Terminology

user environment vs profile:

Definitely profile, since user environment would be too specific; profiles provide a more general abstraction.

User configuration

nix(os) should also be able to link store paths to user homedir paths. It knows (at least for deterministic users) where the homedirs are.

nix tool

attribute name resolution

Two views are clashing here: convenience vs conceptual simplicity

  • conceptually simple: full paths of all namepaces have to be given, e.g

    nix install nixpkgs.pkgs.hello

    or with the renamed namespace from above

    nix install p.hello,

    which is already a lot more convenient but still simple.

  • convenient: an exception for one “special” namespace

    nix install hello

    what is the semantics of that special namespace? Is it simply hardcoded to ~”nixpkgs”~ (which would be a very bad solution)

Extending the namespace scheme from above I propose a special option, nix.namespaces.default, which can be explicitely set. If it is not overwritten by the profile’s namepaces module, the nix internal module uses the first element in the NIX_PATH:

# internal nix namespace module with default
{ config, ... }:
{
  nix.namespaces = rec {
    default = nixpkgs;
    nixpkgs = https://nixos.org;
    mypkgs = /home/bar/nixpkgs;
  };
}

nix help

It should be possible to invoke nix help <subcommand> for each subcommand (no exceptions).

Whether it should open a manpage, pipe it to $PAGER or just output it to stdout is to be discussed. The last option would probably be the cleanest.

nix search

The search by attribute name is not clear to me. How should the syntax be done?

nix install

nix is all about declarativeness and avoiding user-facing state in every way possible. I’m therefore in strong favor of making a declarative nix install the default; even better, why does nix install do anything different than to write to a declarative file? It should only write the package attributes to a function that will be instrumented with the current NIX_PATH values on every invocation of a nix command.

Examples:

nix install hello

nix install nixpkgs.pkgs.python

generates:

{ namespaces, ... }:
with namespaces;
[ default.hello
  nixpkgs.pkgs.python ]

or similar. nix rebuild would then take the path, evaluate the namespaces and fully evaluate the profile.

In that light, nix install should probably renamed to nix add and only with a rebuild should the profile be changed. This also means nix upgrade is unnecessary and nix uninstall is renamed nix remove. The example in transactions would then be:

nix remove chromium \; add firefox \; rebuild

Open questions:

  • what to do when one package is added twice from different repositories?
  • how to handle user defined namespaces in a transparent way?

    e.g. nix add hello with

    namespaces = rec {
      default = p;
      p = config.nix.namespaces.nixpkgs;
    }
        

    is okay, but when the user removes p from his namespaces, nix will probably throw a pretty awkward error that p is missing in the package file. Maybe a hint could be given that it is due to a missing namespace that was still there when the package was installed.

@Anton-Latukha
Copy link

Anton-Latukha commented Sep 4, 2017

Why --help

Everyone already accustomed to that and all tools use command argument --help And everyone expects that option.

And it was deliberate:
Why everywhere --help is used:
When you write commands in console:

1. docker run -it -n nix|... (wait I forgot) ... (ALT + Backspace)
2. docker run -it -n| (ALT + Backspace)
3. docker run -it| (ALT + Backspace)
4. docker run|
5. docker run --help| (Ahh.. Ok!)
6. (Arrow up)
7. docker run --help (ALT + Backspace)
8. docker run ...
# And we used only (ALT + Backspace) here

And with help as argument - we need to remove keys we wrote, and then manually move cursor/retype help and name of command.

1. docker run -it -n nix|... (wait I forgot) ... (ALT + Backspace)
2. docker run -it -n| (ALT + Backspace)
3. docker run -it| (ALT + Backspace)
4. docker run| (CTL + <-)
5. docker |run (<-)
6. docker| run
7. docker help| run (Ahh.. Ok!)
8. (Arrow up)
9. docker help run| (Arrow up)
10. docker run| ...
# And we used (ALT + Backspace) and (CTL + <-)

Other case:

... (thinking)
(wait I forgot)
1. kubectl --help (refreshed knowledge, quit to prompt)
2. (Arrow up)
3. kubectl --help (ALT + Backspace)
4. kubectl convert --help (refreshed knowledge, quit to prompt)
5. (Arrow up)
6. kubectl convert --help (ALT + Backspace)
7. kubectl convert |
8. kubectl convert -f pod.yaml --local -o json
# once more, only (ALT + Backspace)
... (thinking)
(wait I forgot)
1. kubectl help (refreshed knowledge, quit to prompt)
2. (Arrow up)
3. kubectl help convert (refreshed knowledge, quit to prompt)
4. (Arrow up)
5. kubectl help convert| (CTL + <-)
7. kubectl help |convert (ALT + Backspace)
8. kubectl |convert (CTL + ->)
9. kubectl convert|
10. kubectl convert -f pod.yaml --local -o json
# Here, because we can't do double arrow up (no history of this command there) - we use more of complex actions: (CTL + <-), (ALT + Backspace), (CTL + ->)

Here is why help is not an argument in all modern tools, that is why it is --help.

Proposing a nice hack:

As commands in Nix can be long, and Nix is more complex then other package managers - it would be a great hack:

If in command entered found --help - ignore all other options, - show help

Example:

nix install nixpkgs.pkgs.python --help (nix install help showed up)
(Arrow up)
nix install nixpkgs.pkgs.python --help| (ALT + Backspace)
nix install nixpkgs.pkgs.python | (Enter)

For bigger commands with more options - it is even cooller hack.

As you see I looked quite a bit, and I vote to all tweaks are great. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment