7

I'm surprised that 4 digit versioning is not allowed in npm ecosystem:

https://docs.npmjs.com/about-semantic-versioning

enter image description here

However, I have to merge my end product from npm to other systems where 4 digits are allowed. So, my question is:

(how) can we somehow make an exception for our own projects to use 4 digits?

Asqan
  • 4,319
  • 11
  • 61
  • 100
  • In [semver](https://semver.org/) and NPM, which employs semver for versioning, build meta data is ignored for sorting (precedence), but may be used for some matching scenarios. The later are very uncommon and difficult for your customers to make correct use of. – jwdonahue Nov 16 '18 at 20:07
  • 1
    @Asqan, what is the four digit scheme you are targeting? – jwdonahue Nov 16 '18 at 20:20
  • @Asqan, in the NPM environment, you're versioning the NPM package, to what artifact(s) does the four digit version string apply? – jwdonahue Nov 16 '18 at 20:29

2 Answers2

4

You can kind of do it, but you need to substitute the last . with a -. However, this is NON-standard and you should probably make sure to comply with NPM's versioning in case you want to upload your project there. As @ylerjen has pointed out in the comments, when someone uses your package something like 1.2.3-1 will be considered a pre-release and your users won't be upgraded automatically unless they specify the full version, or you publish a new full major-minor-patch version.

E.g. your version would look like 1.1.1-1.

I have seen it in other projects for alpha versions etc and it allows for non-standard version numbers too. Some examples from NPM:

  • vue-class-component@8.0.0-rc.1
  • react-docgen@3.0.0-beta7

However, be aware that when you use any of the npm version major / minor / patch commands it will not increase that number at first but simply truncate everything starting from the first - character. Example:

1.0.6-1

npm version patch

1.0.6

npm version patch

1.0.7

I think this is due to the fact that most people use it to mark a version to be in alpha / beta / rc in that order and when the version is final you keep the version number but remove the suffix.

To automate this, you would need to make your own versioning CLI that knows how to handle your specific versioning scheme.

Lukas Willin
  • 345
  • 3
  • 9
  • 1
    Looks like, this is the closest solution for those who want to use 4 digit versioning – Asqan Apr 25 '22 at 22:37
  • 1
    This answer seems to work, but has an inconvenient. When naming a package with this scheme (e.g. `1.2.3-1`), it will be considered as a pre-release. So when installing, you will need to specify the full version like `npm i mypackage@1.2.3-4`. If you only do `npm i mypackage` it will search for a final (3 digits) and by default won't take prerelease in account. So it can be that you already have a `2.0.0-1`, but the only published final available is `1.2.3`, then it will install `1.2.3`. – ylerjen Sep 21 '22 at 13:30
1

The direct answer to your question is a qualified yes. Some semver supporting package/versioning tools allow quad numeric version strings, but they can't parse them into fields and must use string comparisons or issue an error on comparison, which is usually what you don't want to happen when comparing version strings. In other words, you lose whatever semantics are supposed to be encoded in the four version fields. (See the Coercion topic for a description of NPM's behavior in this case)

Conversions may be possible, but are usually difficult to get right:

The semantics of various 1, 2, 3, 4,...n field version schemes varies, even when the number of fields match up. Where there is a version string such as "1.1.1" that correctly translates to another scheme as "1.1.1", the semantics of the two schemes are the same, or "1.1.1" is a special case. Where the number of fields varies, it's possible that the smaller scheme's field set can be positioned at a fixed offset within the larger schemes fields (with constant values for the remaining fields). It may also be possible to extract a subset of the larger schemes fields, to transfer into the smaller schemes fields. In any case, it is not possible to have a single version string that works in both the larger and smaller scheme without violating the semantics of one or both schemes.

Translating from one scheme to the other, requires a deep understanding of the semantics of both schemes. Many of the four digit schemes are essentially semver with an additional build counter:

X.Y.Z.B
X is major or breaking changes.
Y is minor or non-breaking feature changes.
Z is patch or non-breaking changes that do not add features.
B counts from zero after the last X/Y/Z change.

Translating from such a scheme to semver is not possible, without the entire release history from X'.Y'.Z'.0 - X'.Y'.Z'.n and some means of detecting new features and build breaks between any n and n+1. In cases such as Nuget/.NET, you can lock the B field to zero and apply semver to the remaining fields, then translation from Neget/.Net involves dropping the extra field and from semver implies appending a .0 to the version.

Either adopt semver or don't. If not, you'll just have to put up with various tools squawking about your non-compliant version strings.

jwdonahue
  • 6,199
  • 2
  • 21
  • 43
  • `Some semver supporting package/versioning tools allow quad numeric version strings` I couldn't find any. Can you update your question with links evenutally? I got from your question that conversion is an option but didn't get how to use them practically in my case. What I just want to do is replacing version number in my package.json to a number of 4 digits and being able to build it as a release. – Asqan Nov 19 '18 at 10:31
  • No I think I basically laid out the case for why you don't want to use a quad version where a triple is expected. Conversions are hard to get right. I can't give you much more advice if you don't answer the questions I posed in comments to your OP. – jwdonahue Nov 19 '18 at 20:29
  • @jwdonahue semver allows some kind of pre-release information to be included. I have been trying to figure out how to include that in a 4-number context and would like to propose the following - use numbers 1, 2, and 3 for the first three SemVer numbers as you have said above. But for number 4, encode the pre-release information by increasing it until the final release, at which point number 4 is increased one last time. Any patches to a final release should rev number 3 and clear number 4. Do you see any problems with this scheme, or know of any other way to encode pre-release? – Bondolin Dec 14 '21 at 17:03
  • @Bondolin, it's best to stick to whatever your tool-chain supports. Your proposed scheme is likely to break something somewhere. – jwdonahue Dec 16 '21 at 05:11