[GH-ISSUE #147] Pre-release specification should not allow leading/repeated/trailing/individuals hyphens in identifiers #5211

Closed
opened 2026-06-15 11:16:43 -05:00 by GiteaMirror · 13 comments
Owner

Originally created by @jessewebb on GitHub (Jul 30, 2013).
Original GitHub issue: https://github.com/semver/semver/issues/147

According to the SemVer 2.0.0 spec (point # 9):

A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch version. Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes. Pre-release versions have a lower precedence than the associated normal version. A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.

This does not restrict the usage of the '-' (hyphen) character in string (non-numeric) identifier parts. Therefor, the following are valid versions with pre-release parts:

  • 1.0.0-alpha.-
  • 1.0.0--
  • 1.0.0----
  • 1.0.0-123.---.-
  • 1.0.0-123.ab--cd

The spec for the pre-release portion includes the clause that "Numeric identifiers MUST NOT include leading zeroes". I would suggest that a similar stance is taken on the hyphen character. IMO, only individual hyphens should be allowed in between other alphanumeric characters. Following this, all of the above versions would be invalid. Here are some examples of valid versions which follow this suggested constraint:

  • 1.0.0-alpha.a-5
  • 1.0.0-0-1
  • 1.0.0-rc-1.2-34
  • 1.0.0-a-l-p-h-a.1-2-3
Originally created by @jessewebb on GitHub (Jul 30, 2013). Original GitHub issue: https://github.com/semver/semver/issues/147 According to the SemVer 2.0.0 spec (point # 9): > A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch version. Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes. Pre-release versions have a lower precedence than the associated normal version. A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92. This does not restrict the usage of the '-' (hyphen) character in string (non-numeric) identifier parts. Therefor, the following are valid versions with pre-release parts: - 1.0.0-alpha.- - 1.0.0-- - 1.0.0---- - 1.0.0-123.---.- - 1.0.0-123.ab--cd The spec for the pre-release portion includes the clause that "Numeric identifiers MUST NOT include leading zeroes". I would suggest that a similar stance is taken on the hyphen character. IMO, only individual hyphens should be allowed in between other alphanumeric characters. Following this, all of the above versions would be invalid. Here are some examples of valid versions which follow this suggested constraint: - 1.0.0-alpha.a-5 - 1.0.0-0-1 - 1.0.0-rc-1.2-34 - 1.0.0-a-l-p-h-a.1-2-3
Author
Owner

@Tieske commented on GitHub (Jul 30, 2013):

Why? it's ugly, for sure. But that is not for SemVer to judge.

<!-- gh-comment-id:21818175 --> @Tieske commented on GitHub (Jul 30, 2013): Why? it's ugly, for sure. But that is not for SemVer to judge.
Author
Owner

@jessewebb commented on GitHub (Jul 30, 2013):

No reason really...

I am currently trying to write a SemVer library which can parse strings into versions using RegEx. While developing the RegEx, I was a little confused by the restriction of "no leading zeroes" for the numerical identifiers. In my mind, it provides no additional value besides improved cosmetics. This suggestion is along the same lines.

I guess I also wonder why the hyphen is allowed at all. Is it necessary? Especially considering it is the delimiter for starting the pre-release portion, I think it would be better disallowed all-together. Looking at all the examples I provded above, they are all actually ugly. Is there any valid use-case for needing it?

<!-- gh-comment-id:21818911 --> @jessewebb commented on GitHub (Jul 30, 2013): No reason really... I am currently trying to write a SemVer library which can parse strings into versions using RegEx. While developing the RegEx, I was a little confused by the restriction of "no leading zeroes" for the numerical identifiers. In my mind, it provides no additional value besides improved cosmetics. This suggestion is along the same lines. I guess I also wonder why the hyphen is allowed at all. Is it necessary? Especially considering it is the delimiter for starting the pre-release portion, I think it would be better disallowed all-together. Looking at all the examples I provded above, they are all actually ugly. Is there any valid use-case for needing it?
Author
Owner

@Tieske commented on GitHub (Jul 30, 2013):

on mobile, so no links, but check out some older issues (with many comments) there have been long discussions on this topic.

<!-- gh-comment-id:21819721 --> @Tieske commented on GitHub (Jul 30, 2013): on mobile, so no links, but check out some older issues (with many comments) there have been long discussions on this topic.
Author
Owner

@tbull commented on GitHub (Jul 30, 2013):

While developing the RegEx, I was a little confused by the restriction of "no leading zeroes" for the numerical identifiers. In my mind, it provides no additional value besides improved cosmetics.

This particular rule has a clear purpose. Before we had that rule, version strings X.Y.Z-rc.01 and X.Y.Z-rc.1 were semantically equal (had the same meaning). This made testing two version strings for equality rather difficult. A simple string compare would not be good enough, as two different strings could still mean the exact same version. Now that we have marked one of these string representations invalid, that implementation peculiarity is rectified. On the downside, that makes regular expressions more complicated, but examples have already been given in the discussion, which you find in issue #112.

Maybe we should have something like a log file of decisions, where we list all decisions concisely with their reasoning. That would help newcomers understand what's there and why, and prevent us from repeating the same discussions in the future.

This suggestion is along the same lines.

No, this suggestion has no reason whatsoever besides maybe cosmetics. SemVer is going to be a serious thing, all rules therein (or lack of) are there for a reason. While not all of us agree with each reasoning on each detail, one thing is for sure, that we don't modify the spec without a good reason.

I guess I also wonder why the hyphen is allowed at all. Is it necessary? Especially considering it is the delimiter for starting the pre-release portion, I think it would be better disallowed all-together. Looking at all the examples I provded above, they are all actually ugly. Is there any valid use-case for needing it?

As things are now, there are at least no ambiguities, so it doesn't hurt. So why disallow? Just to prevent ugliness?

<!-- gh-comment-id:21823868 --> @tbull commented on GitHub (Jul 30, 2013): > While developing the RegEx, I was a little confused by the restriction of "no leading zeroes" for the numerical identifiers. In my mind, it provides no additional value besides improved cosmetics. This particular rule has a clear purpose. Before we had that rule, version strings X.Y.Z-rc.01 and X.Y.Z-rc.1 were semantically equal (had the same meaning). This made testing two version strings for equality rather difficult. A simple string compare would not be good enough, as two different strings could still mean the exact same version. Now that we have marked one of these string representations invalid, that implementation peculiarity is rectified. On the downside, that makes regular expressions more complicated, but examples have already been given in the discussion, which you find in issue #112. Maybe we should have something like a **log file of decisions**, where we list all decisions concisely with their reasoning. That would help newcomers understand what's there and why, and prevent us from repeating the same discussions in the future. > This suggestion is along the same lines. No, this suggestion has no reason whatsoever besides maybe cosmetics. SemVer is going to be a serious thing, all rules therein (or lack of) are there for a reason. While not all of us agree with each reasoning on each detail, one thing is for sure, that we don't modify the spec without a good reason. > I guess I also wonder why the hyphen is allowed at all. Is it necessary? Especially considering it is the delimiter for starting the pre-release portion, I think it would be better disallowed all-together. Looking at all the examples I provded above, they are all actually ugly. Is there any valid use-case for needing it? As things are now, there are at least no ambiguities, so it doesn't hurt. So why disallow? Just to prevent ugliness?
Author
Owner

@jessewebb commented on GitHub (Jul 31, 2013):

Thanks for the input! I believe I understand the history behind leading zeroes and hyphens better now.

One other minor issue I can see happening with hyphens allowed is it gives the impression of pseudo-identifiers within string identifiers; seperating parts of an identifier with a hyphen can lead to ambiguity and undesired results in precedence comparisons. For example, the following list is ordered by precedence:

  • 1.0.0-rc-1
  • 1.0.0-rc-10
  • 1.0.0-rc-2
  • 1.0.0-rc1

Even though the spec says otherwise, using hyphens like this will likely cause people to expect numerical ordering of pseudo-sub-sections of an identifier. If the hyphen was not allowed at all, the user would either have to use a single string identifier and the odd ordering may be expected, or they will have to use the '.' separator which will give them the desired result.

  • 1.0.0-rc.1
  • 1.0.0-rc.2
  • 1.0.0-rc.10
  • 1.0.0-rc1

That being said, changing the rules around hyphen usage (including disallowing it all together) is a backwards incompatible change to the spec. Besides avoiding ugliness and ambiguity in complex versions (which should likely be avoided in the first place), it doesn't provide enough value to condone a new major version of the spec. Unless anyone else wants to chime in here on hyphen usage, I am willing to have this issue closed as "won't fix" or whatever.

<!-- gh-comment-id:21872923 --> @jessewebb commented on GitHub (Jul 31, 2013): Thanks for the input! I believe I understand the history behind leading zeroes and hyphens better now. One other minor issue I can see happening with hyphens allowed is it gives the impression of pseudo-identifiers within string identifiers; seperating parts of an identifier with a hyphen can lead to ambiguity and undesired results in precedence comparisons. For example, the following list is ordered by precedence: - 1.0.0-rc-1 - 1.0.0-rc-10 - 1.0.0-rc-2 - 1.0.0-rc1 Even though the spec says otherwise, using hyphens like this will likely cause people to expect numerical ordering of pseudo-sub-sections of an identifier. If the hyphen was not allowed at all, the user would either have to use a single string identifier and the odd ordering may be expected, or they will have to use the '.' separator which will give them the desired result. - 1.0.0-rc.1 - 1.0.0-rc.2 - 1.0.0-rc.10 - 1.0.0-rc1 That being said, changing the rules around hyphen usage (including disallowing it all together) is a backwards incompatible change to the spec. Besides avoiding ugliness and ambiguity in complex versions (which should likely be avoided in the first place), it doesn't provide enough value to condone a new major version of the spec. Unless anyone else wants to chime in here on hyphen usage, I am willing to have this issue closed as "won't fix" or whatever.
Author
Owner

@EddieGarmon commented on GitHub (Jul 31, 2013):

I think it should be on the table for 3.0, as you pointed out in your examples, pseudo-identifiers haven't really been explored. I personally do not like them. I also think that the '-' should be like the '+' and should only be allowed to start an "extension".

This could mean that we have the SemVer core: MAJOR.MINOR.PATCH
and extensions defined as extension character plus dot seperated identifiers consisting of [0-9A-Za-z]
Prerelease: extension '-', included in precedence
BuildMetadata: extension '+', not included in precedence

<!-- gh-comment-id:21874135 --> @EddieGarmon commented on GitHub (Jul 31, 2013): I think it should be on the table for 3.0, as you pointed out in your examples, pseudo-identifiers haven't really been explored. I personally do not like them. I also think that the '-' should be like the '+' and should only be allowed to start an "extension". This could mean that we have the SemVer core: MAJOR.MINOR.PATCH and extensions defined as extension character plus dot seperated identifiers consisting of [0-9A-Za-z] Prerelease: extension '-', included in precedence BuildMetadata: extension '+', not included in precedence
Author
Owner

@tbull commented on GitHub (Aug 1, 2013):

seperating parts of an identifier with a hyphen can lead to ambiguity and undesired results in precedence comparisons

I'd say "counter-intuitive" is the more accurate term here. (It's not really ambigious.)

In your example, if numeric precedence is desired, that can be achieved by using dots as separator, as you already have suggested. Numeric precedence is specified then. I presume, to make the numeric precedence possible is the very reason why numeric identifiers are told apart from non-numeric identifiers at all. (It is quite some hassle to implement that.)

Or, if the hyphens are so nice to look at that they have to stay, leading zeroes can help out here. In this case they're allowed because the identifiers are not purely numeric.

  • 1.0.0-rc-01
  • 1.0.0-rc-02
  • 1.0.0-rc-10

I admit, this is certainly less than perfect. I also agree, that changing the rules regarding this doesn't add enough value to justify a new major release. Then again, i wouldn't like to rule out hyphens entirely, anyway. I wouldn't even rule out double hyphens so people can embed their own semantic scheme within the metadata. You see, there's a lot of room for debate.

I'm not really convinced of the "extension" parts as they're specified now. They are too complicated to understand and too expensive to implement and execute. Eddie hits the nail in saying "pseudo-identifiers haven't really been explored". We should take our time to discuss this matter very patiently to come up with a solid solution and not make quick decisions. The major version number of the spec rises too quickly already.

<!-- gh-comment-id:21924296 --> @tbull commented on GitHub (Aug 1, 2013): > seperating parts of an identifier with a hyphen can lead to ambiguity and undesired results in precedence comparisons I'd say "counter-intuitive" is the more accurate term here. (It's not really ambigious.) In your example, if numeric precedence is desired, that can be achieved by using dots as separator, as you already have suggested. Numeric precedence is specified then. I presume, to make the numeric precedence possible is the very reason why numeric identifiers are told apart from non-numeric identifiers at all. (It is quite some hassle to implement that.) Or, if the hyphens are so nice to look at that they have to stay, leading zeroes can help out here. In this case they're allowed because the identifiers are not purely numeric. - 1.0.0-rc-01 - 1.0.0-rc-02 - 1.0.0-rc-10 I admit, this is certainly less than perfect. I also agree, that changing the rules regarding this doesn't add enough value to justify a new major release. Then again, i wouldn't like to rule out hyphens entirely, anyway. I wouldn't even rule out double hyphens so people can embed their own semantic scheme within the metadata. You see, there's a lot of room for debate. I'm not really convinced of the "extension" parts as they're specified now. They are too complicated to understand and too expensive to implement and execute. Eddie hits the nail in saying "pseudo-identifiers haven't really been explored". We should take our time to discuss this matter _very patiently_ to come up with a solid solution and not make quick decisions. The major version number of the spec rises too quickly already.
Author
Owner

@Tieske commented on GitHub (Aug 1, 2013):

I'm not really convinced of the "extension" parts as they're specified now. They are too complicated to understand and too expensive to implement and execute. Eddie hits the nail in saying "pseudo-identifiers haven't really been explored". We should take our time to discuss this matter very patiently to come up with a solid solution and not make quick decisions. The major version number of the spec rises too quickly already.

I think this is out of scope for semver. It is basically about major, minor, patch and to some extend about prerelease. Prerelease and build are relatively free format to allow for mapping semver on many current formats. This feels like overspecifying imo.

The one debatable thing would be the dash '-' to be removed from the set of valid characters for prerelease. But that is breaking...

<!-- gh-comment-id:21934987 --> @Tieske commented on GitHub (Aug 1, 2013): > I'm not really convinced of the "extension" parts as they're specified now. They are too complicated to understand and too expensive to implement and execute. Eddie hits the nail in saying "pseudo-identifiers haven't really been explored". We should take our time to discuss this matter very patiently to come up with a solid solution and not make quick decisions. The major version number of the spec rises too quickly already. I think this is out of scope for semver. It is basically about major, minor, patch and to some extend about prerelease. Prerelease and build are relatively free format to allow for mapping semver on many current formats. This feels like overspecifying imo. The one debatable thing would be the dash '-' to be removed from the set of valid characters for prerelease. But that is breaking...
Author
Owner

@jessewebb commented on GitHub (Aug 1, 2013):

@tbull Yes I agree; it is counter-intuitive, not ambiguous.

It sounds like no-one (including me) really agrees with the suggestions I originally provided of constraining the hyphen's usage in extensions. But there is a healthy discussions here about whether the hyphen should be allowed at all in the next major version. Should I close this issue and create a new one which suggests that (and link here)? Or just edit the title of this one?

Also, I would like to see what @mojombo thinks of all of this.

<!-- gh-comment-id:21939218 --> @jessewebb commented on GitHub (Aug 1, 2013): @tbull Yes I agree; it is counter-intuitive, not ambiguous. It sounds like no-one (including me) really agrees with the suggestions I originally provided of constraining the hyphen's usage in extensions. But there is a healthy discussions here about whether the hyphen should be allowed at all in the next major version. Should I close this issue and create a new one which suggests that (and link here)? Or just edit the title of this one? Also, I would like to see what @mojombo thinks of all of this.
Author
Owner

@david-a-wheeler commented on GitHub (Jul 14, 2014):

The fundamental problem with hyphens is that they are incompatible with Linux and Unix systems. Linux systems based on .deb (including Debian and Ubuntu) and .rpm (including Red Hat Enterprise Linux, Fedora, and SuSE) forbid dashes in version names; dashes as act as separators between version numbers and other information (such as the architecture a binary runs on). Dashes in version numbers also conflict with other conventions; file myfile-1.2.3-beta.tgz is typically interpreted as "program myfile-1.2.3" with version number "beta". Whups.

Replacing the "-" character with something else, like tilde, seems like the right way to fix this.

This is related to #149 and #209.

<!-- gh-comment-id:48946992 --> @david-a-wheeler commented on GitHub (Jul 14, 2014): The fundamental problem with hyphens is that they are incompatible with Linux and Unix systems. Linux systems based on .deb (including Debian and Ubuntu) and .rpm (including Red Hat Enterprise Linux, Fedora, and SuSE) forbid dashes in version names; dashes as act as separators between version numbers and other information (such as the architecture a binary runs on). Dashes in version numbers also conflict with other conventions; file myfile-1.2.3-beta.tgz is typically interpreted as "program myfile-1.2.3" with version number "beta". Whups. Replacing the "-" character with something else, like tilde, seems like the right way to fix this. This is related to #149 and #209.
Author
Owner

@gvlx commented on GitHub (Oct 5, 2014):

Some questions:

  • Is the tilde '~' character accepted in all filesystems?
  • Is this substitution only because the way .deb and .rpm filenames are interpreted?
  • Are there other cases where this substitution is relevant?
  • Is the case of .deb. and .rpm files sufficiently relevant and important to change a definition to be used on globally?

Thanks,

<!-- gh-comment-id:57951280 --> @gvlx commented on GitHub (Oct 5, 2014): Some questions: - Is the tilde '~' character accepted in all filesystems? - Is this substitution _only_ because the way .deb and .rpm filenames are interpreted? - Are there other cases where this substitution is relevant? - Is the case of .deb. and .rpm files sufficiently relevant and important to change a definition to be used on globally? Thanks,
Author
Owner

@jwdonahue commented on GitHub (Dec 2, 2017):

@jessewebb, unless you intend to pursue this further, please close at your earliest possible convenience.

<!-- gh-comment-id:348669258 --> @jwdonahue commented on GitHub (Dec 2, 2017): @jessewebb, unless you intend to pursue this further, please close at your earliest possible convenience.
Author
Owner

@silkentrance commented on GitHub (Dec 7, 2017):

@jessewebb Simple common sense. If you want it ugly and faeces like, be yourself, both host and guest alike.

While we, the rationale, sniff at it, take a leak at it, marking our territory, moving onward to a working solution that suits all use cases.

Outdated, please close, unless you persist on that faecal matter.

<!-- gh-comment-id:349825921 --> @silkentrance commented on GitHub (Dec 7, 2017): @jessewebb Simple common sense. If you want it ugly and faeces like, be yourself, both host and guest alike. While we, the rationale, sniff at it, take a leak at it, marking our territory, moving onward to a working solution that suits all use cases. Outdated, please close, unless you persist on that faecal matter.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/semver#5211