Brainstorming for RFC: pname and version

I like where this is going.

Potentially +[k=v] could be used for the metadata separator. Eg:

> builtins.parseDrvName "hello-2.10+unstable=2021-04-05"
{ name = "hello"; version = "2.10+unstable=2021-04-05"; }
3 Likes

Or in general things that does not change the versioning, such as ver25.15.

It can be useful for kernel modules: netcon-2.5+unstable=2020-12-12+linux=4.15.10. Looks promising.

But we need to be careful not to over-engineering this.

1 Like

It is similar to derivations tracking old releases - think like GTK2 and GTK3.

Or even better, we can catch an old example: Python2 and Python3. Both Pythons came from the same source tree (biblical pun not intended), but they were released as separate projects.

We can think the same way about nixUnstable and regular nix. They are different projects from the same source tree.

1 Like

@AndersonTorres Here’s a recent one from IRC, not that it needs to be on the list: #nixos-dev on 2021-04-25 — irc logs;


A few thoughts (ignoring pragmatics/compatibility):

  1. The existence of multiple package variants (and difficulty discriminating between them with nix-env) suggests there’s a missing (project?) abstraction. It could, for example, clarify what variants exist and either how to compose their names, or how to parse the names to distinguish them.

  2. I guess there’s a bit of an audience conflict between the documentation here?

    • It’s fine/good for there to be maintainer-focused documentation that is very explicit/detailed on what all depends on the name/version and how to formulate them without breaking stuff.
    • I’m very skeptical that any documentation satisfying the above can be simultaneously appropriate for first-time packagers.
  3. For the benefit of first-time packagers, it may be fruitful to treat each extra sentence/bullet needed to describe a field as a smell that it should be decomposed into simple decisions that:

    • have unambiguous names
    • do not share/overload semantics
    • are easy to get right without ecosystem knowledge
    • are automatically checked/constrained and recomposed to satisfy the ecosystem’s needs/imperatives
2 Likes

About the issue of newcomers, I don’t think they will be overly affected. Usually a new packager wants to insert a single package with an obvious scheming. A newcomer will hardly try to package something like VirtualBox with its modules from master branch.

On the other hand, the issues pointed out are legitimate.

1 Like

I think my point wrt newcomers is that, even if the odds they’ll have something crazy to package are minimal, they still have to try and understand what the packaging guide has to say about names and versions.

That said, the first thing I wanted to package was submitted in bashup-events: init at it's-complicated by abathur · Pull Request #107182 · NixOS/nixpkgs · GitHub, though I ultimately ended up waiting until I had resholve in before doing so, and I definitely had to spend some time puzzling over the docs and asking in IRC.

2 Likes

Good point, but I think it does not affect the decision on frequent corner cases. Indeed once there is no doubt what we want to describe, we should stress that «if some case already fits, you do not need to look further — and hopefully the first case already fits». The corner case list should be a reference but clearly marked unusable as a tutorial.

3 Likes

I think you’re onto something @AndersonTorres . It’s a topic that is ripe for bike-shedding but it would certainly be helpful to get some sort of standard, even if it’s not perfect.

2 Likes

Problems in the paradise: what about RCs? If I’m not wrong, lexicographically 9.3 is before 9.3RC4:

https://github.com/NixOS/nixpkgs/pull/122592

1 Like

I was going to say that’s not a problem we have, but I suppose nix-env does make version comparisons somewhere.

1 Like

Well, I will catch the corresponding snippet from nix-env manual:

   Versions
     The upgrade  operation determines whether a  derivation y is
     an upgrade of a derivation  x by looking at their respective
     name attributes.  The names  (e.g., gcc-3.3.1 are split into
     two  parts:   the  package  name  (gcc),   and  the  version
     (3.3.1). The  version part starts  after the first  dash not
     followed by  a letter. x  is considered  an upgrade of  y if
     their package  names match, and  the version of y  is higher
     that that of x.

     The versions are compared  by splitting them into contiguous
     components of numbers and  letters. E.g., 3.3.1pre5 is split
     into  [3, 3,  1,  pre,  5]. These  lists  are then  compared
     lexicographically  (from   left  to   right).  Corresponding
     components a  and b  are compared as  follows.  If  they are
     both numbers, integer  comparison is used. If a  is an empty
     string and b  is a number, a is considered  less than b. The
     special string component pre (for pre-release) is considered
     to  be less  than  other components.  String components  are
     considered less than number  components. Otherwise, they are
     compared   lexicographically  (i.e.,   using  case-sensitive
     string comparison).

     This is illustrated by the following examples:

1.0 < 2.3  
2.1 < 2.3 
2.3 =  2.3 
2.5 > 2.3 
3.1 >  2.3 
2.3.1 > 2.3 
2.3.1  > 2.3a 
2.3pre1  < 2.3  
2.3pre3 < 2.3pre12  
2.3a < 2.3c 
2.3pre1 < 2.3c 
2.3pre1 < 2.3q

Perfect! Nothing is needed to do for now.

1 Like

For now I will end this Friday and try to write an RFC draft here.

2 Likes

I wrote the following at some point and figure it may be worth pasting here as well for your consideration:

I would propose following Debians model of extended version numbers and using a format along the lines of 0.5.4+nix.20200108 with 0.0.0+nix.20200108 being used for packages without upstream releases.

Regardless of chosen format, I think it would be very unfortunate if the notion of package name and version differs between Nix and Nixpkgs. It is already difficult enough to understand how things interact in the Nix ecosystem and moving away from

getName = s: (builtins.parseDrvName s).name
getVersion = s: (builtins.parseDrvName s).version

is simply confounding when the documentation for builtins.parseDrvName says

Split the string s into a package name and version.
3 Likes

This is almost the same we are doing with 0.5.4+unstable=2020-01-08, and way more readable. nix is not a good name because nix is the programming environment we use to build it. A more appropriated name would be nixpkgs.

Yes, I will do this! 0.5.4+nixpkgs=2020-01-08 is good!

My intention here is to maintain the builtins.parseDrvName intact.

1 Like
  • Regular release:

    • pname is the project name,
    • version is the version as released by the upstream project.
      • version starts with a number; if by any reason the upstream project prepends letters to the version string, we should get rid of this prefix
  • Non regular release (e.g. master branch of a git tree):

    • pname is still the project name,
    • version is composed by the latest released version (default 0.0.0 if the project has no release), followed by followed by a string +unstable=YYYY-MM-DD where YYYY-MM-DD denotes the date it was extracted.
  • Kernel modules:

    • Their versions receive a +linux=${kernel version} appended to the version as defined above.
3 Likes

Uncertain if answered before or out of scope: patched releases?


I learned from the ensuing discussion. That there are two dimensiona to consider:

  • general purpose patches that are meant ro be upstreamed (e.g. reproducability fixes)

  • other patches that are meant to be kept private (relatively rare)

1 Like

This is actually not the same thing as the proposal you are agreeing to (as written).

There are two dimensions: unstable=2021-01-01 and nixpkgs=2021-01-02 (in case we apply any meaningful patches/fixes/wrapping)

1 Like

Wrapping like in makeWrapper? It looks like a Nixpkgs-only thing. No need to encode this.

Patches&fixes? How can we encode this?
Sometimes we use general purpose patches (many of them are downloaded from AUR or Gentoo repos). Usually we prefer to send modifications to upstream, but if the modification is to be keep privately, how can we encode this?

@blaggacao any ideas about the patches issue?

1 Like

if we say we are following Debian style, then yes, changes to Nixpkgs-only wrappers and patches should also be reflected in the version.

(if not, I think the previous unstable marker is better, as we are not talking about timestamping Nixpkgs-related things)

1 Like

Might it be so impractical to differentiate between the two types of patches that it would make sense to just append .patched?

The goal would be to let anybody know that the source code is not equivalent to the upstream’s hash, without further semantical meaning, which might be hard to establish.

1 Like