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.
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.
Problems in the paradise: what about RCs? If I’m not wrong, lexicographically 9.3 is before 9.3RC4:
I was going to say that’s not a problem we have, but I suppose nix-env
does make version comparisons somewhere.
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.
For now I will end this Friday and try to write an RFC draft here.
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.
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.
-
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 (default0.0.0
if the project has no release), followed by followed by a string+unstable=YYYY-MM-DD
whereYYYY-MM-DD
denotes the date it was extracted.
-
-
Kernel modules:
- Their versions receive a
+linux=${kernel version}
appended to the version as defined above.
- Their versions receive a
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)
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)
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?
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)
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.
The point is exactly that we most likely do not want to denote this, and just want to separate whether the base upstream version is an upstream release or upstream development snapshot in some sense
The extreme case would be something like Linux kernel patches like CK. But they are in a category more akin to “user-enabled patches”, in the sense they are not needed for the functioning of the software per se.
I don’t think that signal the patching it is useful anyway.
We still download the pristine upstream sources, and modify them to suit our needs, in a smaller or a bigger extent according to each project. This is the expected workflow.
And our repo is open to all to see; there is no need to encode something that can be seen by merely reading the source code.
The goal is to communicate a commonly used human understanding. We’re trying to find the sweet spot to communicate enough via a simple version string, but not so much that it captures every possible patch/flag/modification; the prefix hash already does that!
Edit: prefix hash of the derivation.
/nix/store/prefixhash-name-version
Prefix hash? Can you explain?
EDIT: prefix hashes can’t help. This is not a format amenable to nix-env, because the hash is not modified monotonically.
@AndersonTorres I feel like input and feedback rounds are exhausted. Cool stuff! Are we ready for a RFC?
(I hope you where able to keep the overview, and I hope I can recover it from an RFC soon )
Yep, I am!
This current week I am full of real life issues to solve, but at the end of week I will be back to this RFC.