www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Timestamping as a solution to versioning hell

reply Alex <AJ gmail.com> writes:
The problem with versioning is that two different entities do not 
version in a way that correlates to a working state:

E.g., take two modules. As they are revisioned, the correlation 
between the revisions is not recorded by versions. If anything 
breaks between through interrelated issues, it cannot be tracked 
by versioning.

Time stamping solves all these problems.

Proper rule to handle all versioning issues - Do not use 
versioning. Use time stamping and immutability:

An entities life time is a function of t, f(t), a history, or a 
github repository change long, so to speak.

Changes happen in time, we can't change the past, but we can 
screw up the future.

By having all changes time stamped, if any state at some time t 
is known, and all future changes do not effect past 
changes(immutability) then the state at some time t is 
stable/fixed/immutable.

For example, if I create a program and it worked perfectly at 
time T AND time stamping/immutability was done perfectly then I 
could always know that my program worked by simply rolling back 
to time T.


That is, imagine all D modules and compiler's time stamped when 
"changed"(not breaking changes don't have to modify the time 
stamp). All previous history is recorded(kept).

Now, suppose I have a working program at some time, say 
2019.05.05. All dependencies that it uses also work because the 
program works.

Now, suppose it is 2050.0.0 and I want to get my program to work! 
It will almost surely fail because all the modules have "changed".

But if I, say, could specify to use all the modules up to 
2019.05.05 then I'd get the original modules that were used at 
that time and every would work because I'd be using the exact 
same state as before[Obviously things might change, such as OS, 
hardware, etc... but ultimately that would have a time stamp too 
and everything would work.. but that is not practical, we are 
just trying to minimize the problems].

-UseVer2019.05.05

would essentially limit to using all the modules up to that 
date... which was the date that the program compiled and hence 
all the code should be identical(any changes to modules after 
that would not be used and hence could not break anything).

Then a dustmite solution could be used where the compiler will 
increase the date(could use binary search) to find the largest 
date that still compiles the source(could check binary difference 
for regression like effects).

E.g., maybe it will download the modules up to 2020 and then an 
error occurs after.

-UseVer2020.0.0

works but after it fails.

The error could be reported and the module that produces it could 
be rolled back and specific changes in the module could be shown 
that caused the failure(a diff between the working module and the 
failed one).

The user then could handle the issue.



I'm only giving a outline of how it would work... but it should 
be clear that versioning is meaningless but time stamping solves 
these problems!

It should have been done from the start, it wasn't, and it has 
created a lot of grief.

Time stamping and immutability correlates all modules with time 
while versioning does not. With versioning we have to keep track 
of all the different versions of modules to make sure our program 
works... a total PITA.

With time stamping, we just have to remember which was the last 
day our program worked(which we can guess, use a search, or just 
look at a time stamp on the exe or source code).

If you agree that this is a much better solution, it then 
requires implementation details:

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

1. All entities: modules, tools, compilers must be time stamped 
in an effective way. For modules this should be in the name 
itself. The current non-time stamped names are aliased to the 
most recent modules by default. (e.g., using -UseVer99999.0.0)


2. All breaking changes to entities produce a new time stamped 
entities. Everything is stored in a proper hierarchical database 
so any entities of any time stamp can be retried.

3. Any non time stamped module is time stamped as coming from 
1000.0.0. Hence, if D was to switch over to time stamped 
versioning all current entities are set at 2019.05.15 and any new 
changes will be time stamped > 2019.05.15


4. The compiler itself is modified to handle this new 
information. One can set the compiler to use a specific time 
stamp, to download entities that are needed/requested(the lasted 
are always included but if one requests older ones then it 
download it, even including the compiler).


Having such a system allows anyone to get back to a working state 
no matter what. Since everything is immutable it means that that 
the history always exists and if a program worked at previous 
point it can work at some time in the future because that 
previous point can be retrieved.

Versioning as we know it will go away.

Upgrading a program is simple and easy and one can always upgrade 
to the latest modules that work and then push through from 
entities that don't by either forcing the entities to use older 
versions or correcting the code.

One could have a nice method of showing the issues and even a 
graphical method that shows the dependency graph in time and 
where things go wrong.

Time is the key, arbitrary versioning is not. Version numbers 
record nothing but that a change occurred, they do not tell one 
anything about when the change occurred... knowing when a change 
occurred is important and time stamping synchronizes ALL changes 
across the universe. Immutability allows us to go back and 
recover the state.

It's time to make a change in the right direction!
May 15 2019
next sibling parent Ron Tarrant <rontarrant gmail.com> writes:
On Wednesday, 15 May 2019 at 09:14:39 UTC, Alex wrote:

 It's time to make a change in the right direction!
It should also put a stop to people putting 2.10 as a later revision than 2.09, although I wouldn't count on it.
May 15 2019
prev sibling parent reply KnightMare <black80 bk.ru> writes:
On Wednesday, 15 May 2019 at 09:14:39 UTC, Alex wrote:

 Time stamping solves all these problems.
 With time stamping, we just have to remember which was the last 
 day our program worked(which we can guess, use a search, or 
 just look at a time stamp on the exe or source code).
I agree in main point: Dlang/Libs should be versioned with using timestamp(optional) as project/compiler/dub. RT will change. Compiler will change. Too difficult store all versions and changes in one EXE/TAR/ZIP, better use last version only and store links to known GITs servers from where it can be restored. Next I will talk about compilers not DUB (I dont use it so dont know it). Compiler and DUB can spawn some another CLI-tool for restore RT/compiler from GITs. - Dlang distro comes with only last version of Phobos(or other name of RT). - Modules (should change compiler) are versioned by Major[.Minor[ExperimentalOrAlphaBetaLetter "abcde.."]] - brackets means "optional" - 2.11f import std.xml:2.0 : someFuncsList; We can (public) import previous version with disable something old or replaced: public import std.xml:1.8 : disable A,B,c,d(XmlDocument); // for concrete implementation of one implementation not all of it. Or we can write new one from scratch. Lettered-versions used explicitly only. Or when we asked "2.0" but 2.0 doesnt exists and RT contains 2.0e for example. Lattered-version can change in future (will some bugs in compilations steps but developer takes such risks). And Unlettered-version allow not to modify code for future when release 2.0 comes. TODO I dont remember version for aug-2017, I can setup version by date std:xml:20170805 (YYYYMMDD where month/day is optional) (some online DB or just list of GIT tags will enough?). - All older versions are stored at GITs servers (for better accessibility lets say in 6 continents). GIT stores tagged versions. When project/compiler see some fixed date or specific version that doesnt exists in current installation it downloads its from one of GITs to some known place (for searching source/libs). TODO compiler can changed too. how to store it: as exe (password leaks can allow malware such EXEs) or as source with compilation possibility? - DUB/project files contains freezed/fixed date (created with "today".init and can be updated manually or interactivelly for current/specific date). Usually u import modules without any version (I am lazy too) means "use current/last one for fixed date". TODO what about compiler name (DMD/LDC/GDC/someNew) and version? how to store it in bin folder? dmd.2.086.0.exe? Well, I cant to see all use-cases now and many questions will raise but IMO versioning allow compile D-code after decades without headache. Versioning is required feature. "experimental" named modules shouldn't be used like moveton. Coz renaming module names in written source is ugly case. Such versioning (as described above) allow - to forget name/version hells. - to use same names for future/new releases. - to re/store all versions in some known place (GITs). - to compile any sample from github/book after any changes in compiler/RT/modules. - other many benefits. Those who do not remember their past are condemned to repeat their mistakes. (c) dontRememberAuthor
May 26 2019
parent KnightMare <black80 bk.ru> writes:
 import std.xml:2.0 : someFuncsList;
two colons are weird, probably need some another syntax.
May 26 2019