June 25, 2020
https://issues.dlang.org/show_bug.cgi?id=20978

          Issue ID: 20978
           Summary: Add versioning to phobos
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: phobos
          Assignee: nobody@puremagic.com
          Reporter: john.michael.hall@gmail.com

In the following thread https://forum.dlang.org/post/hpedmfmtlpewsbgjidpn@forum.dlang.org Andre suggested adding versioning to phobos https://forum.dlang.org/post/rc3a7r$178f$1@digitalmars.com

The scheme is further developed in these two posts https://forum.dlang.org/post/nwkqajtkulvilnvqhipb@forum.dlang.org https://forum.dlang.org/post/eceiamvenhqzvzptktir@forum.dlang.org

As an example, consider restructuring phobos, such that the directory is something like below (assuming that this approach began in 2_89_0 for the sake of simplicity)

  src
   |-- 2_89
   |      |-- 2_89_0
   |      |      |-- moduleA
   |      |      |      ..
   |      |      +-- moduleZZZZ
   |      |-- 2_89_1
   |      |      |-- moduleA
   |      |      |      ..
   |      |      +-- moduleZZZZ
   |      +-- latest
   |             |-- moduleA
   |             |      ..
   |             +-- moduleZZZZ
   |-- 2_90
   |      |-- 2_90_0
   |      |      |-- moduleA
   |      |      |      ..
   |      |      +-- moduleZZZZ
   |      |-- 2_90_1
   |      |      |-- moduleA
   |      |      |      ..
   |      |      +-- moduleZZZZ
   |      |-- 2_90_2
   |      |      |-- moduleA
   |      |      |      ..
   |      |      +-- moduleZZZZ
   |      +-- latest
   |             |-- moduleA
   |             |      ..
   |             +-- moduleZZZZ
   |-- 2_91
   |      |-- 2_91_0
   |      |      |-- moduleA
   |      |      |      ..
   |      |      +-- moduleZZZZ
   |      |-- 2_91_1
   |      |      |-- moduleA
   |      |      |      ..
   |      |      +-- moduleZZZZ
   |      +-- latest
   |             |-- moduleA
   |             |      ..
   |             +-- moduleZZZZ
   |-- 2_92
   |      |-- 2_92_0
   |      |      |-- moduleA
   |      |      |      ..
   |      |      +-- moduleZZZZ
   |      +-- latest
   |             |-- moduleA
   |             |      ..
   |             +-- moduleZZZZ
   +-- latest
          |-- moduleA
          |      ..
          +-- moduleZZZZ



-------------

Setting this up initially, we would have

module std.2_89.2_89_0.moduleA;
//and then definitions of funA, funB, etc.

module std.2_89.latest.moduleA;
public import std.2_89.2_89_0.moduleA;

//saved to ./src/latest/modulaA
module std.moduleA;

version(std_latest) {
    version = std_2_89;
}
version(std_stable) {
    version = std_2_89;
}
version(std_2019) {
    version = std_2_89;
}
version(std_2_89) {
    public import std.2_89.latest.moduleA;

-------------

If we have the bug fix 2.89.1 to funB, then we have would update as below

//no change to std.2_89.2_89_0.moduleA

module std.2_89.2_89_1.moduleA;
public import std.2_89.2_89_0.moduleA; //might need to make these selective
//update to funB

module std.2_89.latest.moduleA;
public import std.2_89.2_89_1.moduleA;

//no change to std.moduleA

-------------

For the next version 2.90.0, then we would update as follows

//no change to std.2_89.2_89_0.moduleA
//no change to std.2_89.2_89_1.moduleA
//no change to std.2_89.latest.moduleA

module std.2_90.2_90_0.moduleA;
public import std.2_89.latest.moduleA;
//any new functions or changes from 2_89

module std.2_90.latest.moduleA;
public import std.2_90.2_90_0.moduleA;

//saved to ./src/latest/modulaA
module std.moduleA;

version(std_latest) {
    version = std_2_90;
}
version(std_stable) {
    version = std_2_89;
}
version(std_2020) {
    version = std_2_90;
}
version(std_2019) {
    version = std_2_89;
}
version(std_2_89) {
    public import std.2_89.latest.moduleA;
}
version(std_2_90) {
    public import std.2_90.latest.moduleA;
}

and so on up thereafter.

One benefit of this design are that it would allow users access to old versions of phobos through use of version statement. It would also allow bug fixes to old versions of phobos to propagate upward, though patches will need to be manually applied when a function is given a different implementation in a later version.

One consequence of this design is that it avoids the repetition of code through the use of public imports. However, this also means that the most recent version of each function is not actually in the "latest" folders. They are spread out among many files, which requires the user to search for it. If this is considered a significant problem, then the underlying files, such as module std.2_90.latest.moduleA can avoid public imports of past versions. The rest of the structure can remain the same, though it would require more manual adjustment if there are bug fixes in old versions of phobos.

--