4 digit versioning in npm - npm

I'm surprised that 4 digit versioning is not allowed in npm ecosystem:
https://docs.npmjs.com/about-semantic-versioning
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?

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 (I don't think it can brake anything but it's still a good to keep the versioning consistent on the plattform.)
Eg. your version would look like 1.1.1-1.
I have seen in it other projects for alpha versions etcs 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 normally 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.

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.

Related

Can I set a maximum value for a number in protobuf?

In protobuf, we only have the choice of using signed or unsigned 32- or 64-bit integer to limit the range of a value.
However, the datastructure I want to define contains a mixture of 8-bit, 16-bit and 32-bit integers to save space on embedded devices. On them, the datastructure is also implemented somewhat differently and requires reserved special values for some fields, so the maximum number for them is not a power of 2.
On these embedded devices, the protobuf definition is only used for transmission to and from them, not for actual storage. So I could just limit the numbers when reading them in.
However, I'd rather define these maximum values in the .proto or .options file to make sure all client applications are aware of these limitations.
Is there a way to do this?
I know there are field options, but the ones listed here does not include an option for this. It is possible to create custom options, but that seems to require writing a compiler extension, which means I have to manually implement this limit checking for every language I want to compile to, and that costs more time than it will ever save.
This is not possible in protobuf by default, and the specification includes no syntax to enforce limits like this.
However, some third party implementations do include such support.
For example, my own nanopb has the int_size option:
int_size: Override the integer type of a field. (To use e.g. uint8_t to save RAM.)
This will return an error at runtime from pb_decode() if the value does not fit in the field.
No there is no syntax for expressing that intent and no inbuilt tool / codegen that will enforce the rule you want to add. You would need to handle this manually.

Difference between yarn/npm5 lockfiles and exact package versions?

My simple question is: why can't I just use exact versions in my package.json? How is this different from a lockfile?
The main difference is that lockfiles also lock nested dependencies - all of the dependencies of your dependencies, and so on. Managing and tracking all of those changes can be incredibly difficult, and the number of packages that are used can grow exponentially.
There are also situations where you cannot manually specify that a particular version of a package should be used - consider 2 libraries that specify foo at ~1.0.0 and ~2.0.0 respectively. The difference in major version tells us that the API of foo#v1 is not going to match the API of foo#v2, so there's no way you could override the package version at your app level without causing conflicts and failures.
Finally, you might wonder "why have semver at all then? Why not just have all packages manually specify the exact version of their dependencies?" One of the main advantages of semver is it means you don't have to update every dependency in the tree whenever a sub-dependency updates. If I rely on foo, and foo relies on bar, and bar just had a critical bug that was patched, and we're using exact versions for everything, then foo must also be updated before I can get the fix. If foo and bar have different maintainers, or if foo is abandoned, that could take a while and I may need to fork the project (something I've done more than once in Java-land).
This is very useful for maintaining ecosystems of libraries because it fundamentally reduces the amount of maintenance work required per-node in the dependency tree, making it easier to extract libraries and patterns. I once had an early project where we were building a component library that used exact versions, and any time the core library containing shared functionality was updated, we had to submit a PR to each of the other packages to update the version, and sometimes followup PRs to components that depended on those. Needless to say, we consolidated the packages after a few months.
Hope that helps!

project.json versioning format

I'm looking for a formal definition of version number formats for .NET Core project.json files.
version
Visual studio creates a default version number of "1.0.0-*". I would love for this to mean the * gets updated on successive builds (it doesn't). The build version number is 1.0.0. What does the * mean and what are the legal possibilities?
dependencies
I expected the dependency numbering to follow the nuget versioning rules given that KPM is basically a nuget front-end, but it doesn't appear to support bracket numbering (eg "[1,2)") - I get "not a valid version string" when I try anything other than a blank or x.x-* format.
Outside of the source, does anyone have a link to a formal definition?
I'm not sure what's wrong with looking into the source for a definition. I think that's the most accurate place to search, especially now that vNext is hosted on GitHub.
Looking at the exception described, we're pointed to SemanticVersion.cs.
In the method TryParseInternal, it's fairly obvious why you're running into issues when attempting to declare min/max versions that way. There is simply no handling for [,] or (,) built into that method.
If we look into the regular NuGet version specification, it's obvious that TryParseVersionSpec does have this handling built in.
As for documentation specifying acceptable formats, you'll probably have to wait until it's out of CTP status. If you believe it's an issue, you should document it in GitHub. The contributors are very responsive to these types of issues. Personally I'm not sure if there's a need for setting a maximum version of a dependency when it's deployed with your build.

cmake LibFindMacros set library minimum version number

In Cmake, when using LibFindMacros, is there a way to tell cmake that a library needs to have a minimum version number? The information I've found on http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries doesn't say anything about that.
No... No integrated version support in finding libraries with cmake.
My guess is that in most cases each library has its own way of defining its version and therefore it makes it a daunting task to find out what that version really is. On a Linux system, you could try to query the system with a tool such as dpkg or rpm, but those would only give you the version of the installed library, not the one you're about to compile against.
There is an issue talking about that here:
http://public.kitware.com/Bug/view.php?id=8396
Now, the macros you mentioned have a function to extract a version assuming there is #define <version> <#.#.#> or something of the sort in a header file for that library.
https://github.com/Tronic/cmake-modules/blob/master/LibFindMacros.cmake
# Extracts a version #define from a version.h file, output stored to <PREFIX>_VERSION.
# Usage: libfind_version_header(Foobar foobar/version.h FOOBAR_VERSION_STR)
# Fourth argument "QUIET" may be used for silently testing different define names.
# This function does nothing if the version variable is already defined.
function (libfind_version_header PREFIX VERSION_H DEFINE_NAME)
...
So you use this macro, retrieve a #define from a .h file and then compare that value saved in ${PREFIX}_VERSION in your own way. In my libraries, I often have a set of 3 or 4 #define with the major, minor, and release version numbers. That makes it easy to compare. When you get all those numbers together, such as 3.2.4.1, it makes it harder to compare without specialized code... (again, that makes it really complicated for cmake to support a version comparison scheme.)
Note that the macro expects ${PREFIX}_INCLUDE_DIR to be set. It looks like libfind_pkg_detect() sets that variable so you need to first detect the location of the library (headers) and then you can gather the version in a header.
Update:
Note that there are specialized compare operators you can use to compare two version strings against each other:
if(${PREFIX}_VERSION VERSION_EQUAL 1.2.9)
The only problem is that it's going to be a cmake version comparison algorithm which may not match the corresponding project algorithm. That means it's limited to just numbers separated by periods. I'm not too sure when these operators were added to cmake.

Examples of Semantic Version Names

I have been reading about semver. I really like the general idea. However, when it comes to putting it to practice, I feel like I'm missing some key pieces of information. I'm not sure where the name of a library exists, or what to do with file variants. For instance, is the file name something like [framework]-[semver].min.js? Are there popular JavaScript frameworks that use semver? I don't know of any.
Thank you!
Let me try to explain you.
If you are not developing a library that you like to keep for years to come, don't bother about it.. If you prefer to version every development, read the following.
Suppose you are an architect or developer developing a library that is aimed to be used by hundreds of developers over time, in a distributed manner. You really need to be cautious of what you are doing, what your developers are adding (so interesting features that grabs your attention to push those changes in the currently distributed file). You dont know how do you tell your library users to upgrade. In what scenarios? People followed some sort of versioning, and interestingly, their thoughts all are working fine.
Then why do you need semver ?
It says "There should be a concrete specification for anything for a group of people to follow anything collectively, even though they know it in their minds". With that thought, they made a specification. They have made their observation and clubbed all the best practices in the world about versioning software mainly, and given a single website where they listed them. that is semver.org. Its main principles are :
Imagine you have already released your library with a version "lib.1.0.98", Now follow these rules for subsequent development.
Let your library is bundled and named as xyz and,
Given a version number MAJOR.MINOR.PATCH, (like xyz.MAJOR.MINOR.PATCH), increment the:
1. MAJOR version when you make incompatible API changes
(existing code of users of your library breaks if they adapt this without code changes in their programs),
2. MINOR version when you add functionality in a backwards-compatible manner
(existing code works, and some improvements in performance and features also), and
3. PATCH version when you make backwards-compatible bug fixes.
Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.
If you are not a developer or are not in a position to develop a library of a standard, you need not worry at all about semver.
Finally, the famous [d3] library follows this practice.
Semantic Versioning only defines how to name your versions. It does not specify what you will do with your version number afterwards. You can put the version numbers in package names, you can store it in a properties file inside your application, or just publish it in a wiki. All those options are opened to discussion and not part of the problem space addressed by SemVer.
semver is used by npm and bower (and perhaps some other tools) for dependency management. Using semver it is possible to decide which versions of which packages to use if multiple libraries used depend on the same library.
As others have said, semantic versioning is a standard versioning scheme that tells your users which versions of your library should be compatible with each other, and which ones are not.
The idea, is to be able to give your users more confidence that it's safe to upgrade to a newer patch/version, because it's tried, tested, and true to being backwards compatible with the previous version (minor increments). That is, perceptively that's what your telling your users.
As far as tooling goes, I don't do much in javascript, but I typically let my build server handle stamping my assemblies etc with the correct version. I have a static major number I upgrade whenever I make breaking changes, a static minor number I upgrade everytime I add new features, and an auto-incrementing Patch number whenever I checkin bug fixes.
Especially if this is a javascript library you plan to share on a public repository of some kind (nuget, gem, etc) you probably want some for of automated packaging system, and you put the logic in there for specifying your version number (in the package meta data, in the name of the javascript file, which is typically the standard I've seen).
Take a look at sbt which is the Scala Build Tool. In it, we write dependencies like this:
val scalatest = "org.scalatest" %% "core" % "2.1.7" "test"
val jodatime = "org.joda" % "jodatime" % "1.4.5"
Wherein the operator %% means "the current version of Scala that you're building." Packaging things in this language generally create JAR files with the name like this <my project>_<scala version>_<library version>.jar which is quite handy for semantically naming things automagically. The % operator can be interpreted as "don't version this part."
That said, this resulted from the fact that the same library compiled to different Scala versions were not binary compatible with each other. So it was more as a result of, rather than a conscious design choice, the binary incompatibilities.