Vcpkg: Idea: partial handling of semantic-versioning as a way to provide some way of choosing specific versions of libraries

Created on 2 Jun 2019  路  8Comments  路  Source: microsoft/vcpkg

First of all, I've already seen and read #1681

I'd like to start by disagreeing with one statement:

This approach minimizes the burden on library authors and maintainers (how many boost versions must you test against? We say: only the latest supported upstream release), though the user experience can be rough as you've experienced and we do want to improve it in the future.

Of course. That's a good idea. As long as the library updates are compatible. However, "nowadays" we are a bit more aware about versioning issues and library authors often use more-or-less semantic versioning. In face or a large change that is meant/expected/etc to be not compatible, library authors often change the major number of that library, and the consumers often want to stay with their old major number.

As far as I quicky looked through the vcpkg project and structure of 'ports', it should be pretty easy to achieve. It could be added as a section to the installation command:

vcpkg install foobar:3:x86-windows

where the ":3:" section marks the major tag number.

Of course, from this there's a short path to

vcpkg install foobar:3.4-alpha-56-pretest-demo:x86-windows

and so on. I understand that this leads to the more-hellish part of dependency management that we dont want to dive into (for now?).

However, for the purpose of at least _some_ way of managing the major versions (which seem pretty important..) there's one really simple trick:

(here's the actual request, the ^ was an lenghy intro)
_Please consider adding major number version as a suffix to the library name._

That one is easy. I think it doesn't require any changes to the internal parts, just small edit to the ports library.. for example:

pdcurses ----> pdcurses-v3
sfml ---> sfml-v2

Using this scheme, which I think comes at almost no cost, when a new breaking major version shows up in any library (say, pdcurses publish version 4.0), its users will still stay with the previous one. Library authors may choose how long they want to keep patching both version and when to stop patching the old one, and users may decide when to switch to the new major number, while still being able to update their dependency safely in bounds of their currently-selected major version.

Most helpful comment

What if we enabled it so we could create subfolder that contained portfiles for old versions.

For example here's what the boost folder could look like:

 | Boost 
 |  | /desktop
 |  | /uwp
 |  | /boost-1.70
 |  |  | /desktop
 |  |  | /uwp
 |  |  | 0001-Fix-boost-ICU-support.patch
 |  |  | CONTROL
 |  |  | portfile.cmake
 |  |  | usage
 |  | 0001-Fix-boost-ICU-support.patch
 |  | CONTROL
 |  | portfile.cmake
 |  | usage

Then when someone does ./vcpkg install boost it will install the top level (latest) version of boost (As it does already). But if someone writes ./vcpkg install boost:boost-1.70 or some sort of syntax similar, it will use the install instructions located in the boost-1.70 folder.

This could be a non-disruptive approach to implementing versioning. Every time a new version comes out, you plop the existing files in a new folder, and then modify the top level to fit the new version.

All of these perfectly working portfiles for old versions are just getting erased every time there's an update. May as well make it standard to toss them in a folder before overwriting them.

All 8 comments

This would be a great feature for vcpkg! It would make it much more flexible for users to choose the version of packages they need. Although some refactor and format change in control file is need. But should be not a big change (defining multiple versions instead of one single version).

Not sure I completely understand this. Would foobar-v2 and foobar-v3 be separate packages/ports? Or two mutually exclusive versions of the same port?

Using the major version as part of the port name is already been done in some cases (e.g. qt5). Renaming all other ports would however be pretty disruptive

Would foobar-v2 and foobar-v3 be separate packages/ports? Or two mutually exclusive versions of the same port?

I see it more like mutually exclusive options. Using foobar-v2 and foobar-v3 in the same code project sounds like a death wish, considering that the headers/imports would probably get totally mixed up.

Renaming all other ports would however be pretty disruptive

I'd say "pretty disruptive" would be to leave it as is, so when a library Foobar (v2.x) gets a braking change and is now Foobar (v3.x), current handling would be to just update it and push the breaking change to all unsuspecting consumers :)

Actually, I agree that renaming all _current_ libs to foo-X right now would break current uses. Noone has it as foo-X right now, so it'd break all builds. However, what I want to suggest, is to use this scheme, name-major, for all _future_ major versions. Let the Foobar (v2.x) library stay "foobar" for now, but when it gets a major change, leave "foobar" as is, bound to 2.x, and register the newer 3.x version as foobar-3, or something similar.

Then I guess the simplest way would still be to create separate ports and to add a field in the control.txt file that list packages which can't be installed simultaneously with the particular port.

This might make ci testing a bit more difficult, because now multiple different combinations need to be tested.

Of course the other can of worms this opens is the question which version x of libX, libY should list as its dependency.

My relevant post here #2823. Major version specifying is not enough. Libraries like Boost only have minor version changing, it doesn't make a difference for Boost since there's no Boost v2.

Again, really weird that vcpkg is still struggling from the awkward git-based versioning...

What if we enabled it so we could create subfolder that contained portfiles for old versions.

For example here's what the boost folder could look like:

 | Boost 
 |  | /desktop
 |  | /uwp
 |  | /boost-1.70
 |  |  | /desktop
 |  |  | /uwp
 |  |  | 0001-Fix-boost-ICU-support.patch
 |  |  | CONTROL
 |  |  | portfile.cmake
 |  |  | usage
 |  | 0001-Fix-boost-ICU-support.patch
 |  | CONTROL
 |  | portfile.cmake
 |  | usage

Then when someone does ./vcpkg install boost it will install the top level (latest) version of boost (As it does already). But if someone writes ./vcpkg install boost:boost-1.70 or some sort of syntax similar, it will use the install instructions located in the boost-1.70 folder.

This could be a non-disruptive approach to implementing versioning. Every time a new version comes out, you plop the existing files in a new folder, and then modify the top level to fit the new version.

All of these perfectly working portfiles for old versions are just getting erased every time there's an update. May as well make it standard to toss them in a folder before overwriting them.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jack17529 picture jack17529  路  3Comments

husseinalihazime picture husseinalihazime  路  3Comments

aspioupiou picture aspioupiou  路  3Comments

F0I0l0I0P picture F0I0l0I0P  路  3Comments

pakdel picture pakdel  路  3Comments