Skip to content

Commit de02eda

Browse files
authored
Merge pull request #79 from twpol/feature/unstable-version-numbers
Update version calculation for new unstable versions
2 parents fb99b88 + 31cd666 commit de02eda

File tree

9 files changed

+130
-174
lines changed

9 files changed

+130
-174
lines changed

Build.cmd

Lines changed: 7 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,10 @@ IF "%Mode%" == "Stable" (
8787
)
8888
)
8989

90-
REM Get code revision.
91-
SET Revision=000
92-
IF EXIST ".svn" (
93-
FOR /F "usebackq tokens=1" %%R IN (`svn --non-interactive info --show-item revision .`) DO SET Revision=%%R
94-
)
95-
IF EXIST ".git" (
96-
FOR /F "usebackq tokens=1" %%R IN (`git describe --first-parent --always`) DO SET Revision=%%R
97-
)
98-
IF "%Revision%" == "000" (
99-
>&2 ECHO WARNING: No Subversion or Git revision found.
100-
)
90+
REM Get product version and code revision.
91+
FOR /F "usebackq tokens=1* delims==" %%A IN (`CALL GetVersion.cmd %Mode%`) DO SET %%A=%%B
92+
SET Version=%OpenRails_Version%
93+
SET Revision=%OpenRails_Revision%
10194

10295
REM Restore NuGet packages.
10396
nuget restore Source\ORTS.sln || GOTO :error
@@ -116,19 +109,6 @@ REM Set update channel.
116109
>>Program\Updater.ini ECHO Channel=string:%Mode% || GOTO :error
117110
ECHO Set update channel to "%Mode%".
118111

119-
REM Set version number.
120-
IF NOT "%Version%" == "" (
121-
>Program\Version.txt ECHO %Version%. || GOTO :error
122-
ECHO Set version number to "%Version%".
123-
) ELSE (
124-
>Program\Version.txt ECHO X || GOTO :error
125-
ECHO Set version number to none.
126-
)
127-
128-
REM Set revision number.
129-
>Program\Revision.txt ECHO $Revision: %Revision% $ || GOTO :error
130-
ECHO Set revision number to "%Revision%".
131-
132112
REM Build locales.
133113
PUSHD Source\Locales && CALL Update.bat non-interactive && POPD || GOTO :error
134114

@@ -147,20 +127,10 @@ IF NOT EXIST "Program\Content\Web" MKDIR "Program\Content\Web"
147127
XCOPY "Source\RunActivity\Viewer3D\WebServices\Web" "Program\Content\Web" /S /Y || GOTO :error
148128

149129
REM Copy version number from OpenRails.exe into all other 1st party files
150-
SET VersionInfoVersion=0.0.0.0
151-
IF NOT "%Version%" == "" (
152-
SET VersionInfoVersion=%Version%.%Revision%
153-
) ELSE (
154-
FOR /F "usebackq tokens=1" %%V IN (`rcedit-x86.exe "Program\OpenRails.exe" --get-version-string FileVersion`) DO SET VersionInfoVersion=%%V
155-
)
156-
IF "%VersionInfoVersion%" == "0.0.0.0" (
157-
>&2 ECHO ERROR: No VersionInfoVersion found in "Program\OpenRails.exe".
158-
GOTO :error
159-
)
160130
FOR %%F IN ("Program\*.exe", "Program\Orts.*.dll", "Program\Contrib.*.dll", "Program\Tests.dll") DO (
161-
rcedit-x86.exe "%%~F" --set-product-version %VersionInfoVersion% --set-file-version %VersionInfoVersion% --set-version-string ProductVersion %VersionInfoVersion% --set-version-string FileVersion %VersionInfoVersion% || GOTO :error
131+
rcedit-x86.exe "%%~F" --set-product-version %Revision% --set-version-string ProductVersion %Version% || GOTO :error
162132
)
163-
ECHO Set product and file version information to "%VersionInfoVersion%".
133+
ECHO Set product version information to "%Version%".
164134

165135
REM *** Special build step: signs binaries ***
166136
IF NOT "%JENKINS_TOOLS%" == "" (
@@ -196,7 +166,7 @@ IF "%Mode%" == "Stable" (
196166
IF %ERRORLEVEL% GEQ 8 GOTO :error
197167
ROBOCOPY /MIR /NJH /NJS "Program\Documentation" "Open Rails\Documentation"
198168
IF %ERRORLEVEL% GEQ 8 GOTO :error
199-
>"Source\Installer\OpenRails shared\Version.iss" ECHO #define MyAppVersion "%Version%.%Revision%" || GOTO :error
169+
>"Source\Installer\OpenRails shared\Version.iss" ECHO #define MyAppVersion "%Version%" || GOTO :error
200170
iscc "Source\Installer\OpenRails from download\OpenRails from download.iss" || GOTO :error
201171
iscc "Source\Installer\OpenRails from DVD\OpenRails from DVD.iss" || GOTO :error
202172
CALL :move "Source\Installer\OpenRails from download\Output\OpenRailsTestingSetup.exe" "OpenRails-%Mode%-Setup.exe" || GOTO :error

GetVersion.cmd

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
@ECHO OFF
2+
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
3+
4+
SET Mode=%~1%
5+
FOR /F "usebackq tokens=1-2 delims=-" %%A IN (`git describe --long --exclude=*-*`) DO (
6+
SET Git.Tag=%%A
7+
SET Git.Commits=%%B
8+
)
9+
FOR /F "usebackq tokens=1-4 delims=." %%A IN (`ECHO %Git.Tag%.0.0`) DO SET Revision=%%A.%%B.%%C.%Git.Commits%
10+
GOTO %Mode%
11+
12+
13+
:stable
14+
FOR /F "usebackq tokens=* delims=-" %%A IN (`git describe`) DO SET Version=%%A
15+
GOTO :done
16+
17+
18+
:testing
19+
FOR /F "usebackq tokens=* delims=-" %%A IN (`git describe --long --exclude=*-*`) DO SET Version=%Mode:~0,1%%%A
20+
GOTO :done
21+
22+
23+
:unstable
24+
SET TZ=UTC
25+
FOR /F "usebackq tokens=1-4 delims=." %%A IN (`git log -1 --pretty^=format:%%ad --date=format-local:%%Y.%%m.%%d.%%H%%M`) DO (
26+
SET Version=%Mode:~0,1%%%A.%%B.%%C-%%D
27+
SET Revision=0.%%A.%%B%%C.%%D
28+
)
29+
GOTO :done
30+
31+
32+
:done
33+
ECHO OpenRails_Version=%Version%
34+
ECHO OpenRails_Revision=%Revision%

Source/Launcher/Launcher.csproj

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@
6262
<PropertyGroup>
6363
<PreBuildEvent>
6464
</PreBuildEvent>
65-
<PostBuildEvent>echo $Revision: 000 $&gt;Revision.txt
66-
date /t&gt;&gt;Revision.txt
67-
time /t&gt;&gt;Revision.txt</PostBuildEvent>
65+
<PostBuildEvent>
66+
</PostBuildEvent>
6867
</PropertyGroup>
6968
</Project>

Source/Menu/Menu.csproj

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,7 @@
204204
<PropertyGroup>
205205
<PreBuildEvent>
206206
</PreBuildEvent>
207-
<PostBuildEvent>echo $Revision: 000 $&gt;Revision.txt
208-
date /t&gt;&gt;Revision.txt
209-
time /t&gt;&gt;Revision.txt
210-
211-
REM Copy Spanish manual until we can make its RST files part of the build.
207+
<PostBuildEvent>REM Copy Spanish manual until we can make its RST files part of the build.
212208
CD ..\
213209
IF EXIST "Program\Documentation\es" RMDIR "Program\Documentation\es" /S /Q
214210
IF NOT EXIST "Program\Documentation\es" MKDIR "Program\Documentation\es"

Source/Menu/ResumeForm.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public class Save
9090
public bool IsMultiplayer { get; private set; }
9191
public bool DbfEval { get; private set; } //Debrief Eval
9292

93-
public Save(string fileName, string currentBuild, int youngestFailedToResume)
93+
public Save(string fileName, string youngestVersionFailedToRestore)
9494
{
9595
File = fileName;
9696
System.Threading.Thread.Sleep(10);
@@ -101,7 +101,7 @@ public Save(string fileName, string currentBuild, int youngestFailedToResume)
101101
var version = inf.ReadString().Replace("\0", ""); // e.g. "0.9.0.1648" or "X1321" or "" (if compiled locally)
102102
var build = inf.ReadString().Replace("\0", ""); // e.g. 0.0.5223.24629 (2014-04-20 13:40:58Z)
103103
var versionOrBuild = version.Length > 0 ? version : build;
104-
var valid = VersionInfo.GetValidity(version, build, youngestFailedToResume);
104+
var valid = VersionInfo.GetValidity(version, build, youngestVersionFailedToRestore);
105105
// Read in multiplayer flag/ route/activity/path/player data.
106106
// Done so even if not elegant to be compatible with existing save files
107107
var routeNameOrMultipl = inf.ReadString();
@@ -213,7 +213,6 @@ void LoadSaves()
213213
{
214214
var saves = new List<Save>();
215215
var directory = UserSettings.UserDataFolder;
216-
var build = VersionInfo.Build.Contains(" ") ? VersionInfo.Build.Substring(VersionInfo.Build.IndexOf(" ") + 1) : null;
217216
var prefix = String.Empty;
218217

219218
if (SelectedAction == MainForm.UserAction.SinglePlayerTimetableGame)
@@ -244,7 +243,7 @@ void LoadSaves()
244243
// SavePacks are all in the same folder and activities may have the same name
245244
// (e.g. Short Passenger Run shrtpass.act) but belong to a different route,
246245
// so pick only the activities for the current route.
247-
var save = new Save(saveFile, build, Settings.YoungestFailedToRestore);
246+
var save = new Save(saveFile, Settings.YoungestVersionFailedToRestore);
248247
if (save.RouteName == Route.Name)
249248
{
250249
if (!save.IsMultiplayer ^ Multiplayer)
@@ -447,11 +446,10 @@ void buttonDeleteInvalid_Click(object sender, EventArgs e)
447446
var directory = UserSettings.UserDataFolder;
448447
if (Directory.Exists(directory))
449448
{
450-
var build = VersionInfo.Build.Contains(" ") ? VersionInfo.Build.Substring(VersionInfo.Build.IndexOf(" ") + 1) : null;
451449
var deletes = 0;
452450
foreach (var saveFile in Directory.GetFiles(directory, "*.save"))
453451
{
454-
var save = new Save(saveFile, build, Settings.YoungestFailedToRestore);
452+
var save = new Save(saveFile, Settings.YoungestVersionFailedToRestore);
455453
if (save.Valid == false)
456454
{
457455
foreach (var fileName in new[] {

Source/ORTS.Common/VersionInfo.cs

Lines changed: 65 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -29,69 +29,42 @@ namespace ORTS.Common
2929
public static class VersionInfo
3030
{
3131
static readonly string ApplicationPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
32-
// GetRevision() must come before GetVersion()
33-
/// <summary>Revision number, e.g. Release: "1648", experimental: "1649", local: ""</summary>
34-
public static readonly string Revision = GetRevision("Revision.txt");
35-
/// <summary>Full version number, e.g. Release: "0.9.0.1648", experimental: "X.1649", local: ""</summary>
36-
public static readonly string Version = GetVersion("Version.txt");
37-
/// <summary>Full build number, e.g. "0.0.5223.24629 (2014-04-20 13:40:58Z)"</summary>
38-
public static readonly string Build = GetBuild("ORTS.Common.dll", "OpenRails.exe", "Menu.exe", "RunActivity.exe");
32+
33+
/// <summary>Full version, e.g. stable: "1.4", testing: "T1.4-1-g1234567", unstable: "U2021.01.01-0000", local: ""</summary>
34+
public static readonly string Version = GetVersion("OpenRails.exe");
35+
36+
/// <summary>Full build, e.g. "0.0.5223.24629 (2014-04-20 13:40:58Z)"</summary>
37+
public static readonly string Build = GetBuild("OpenRails.exe");
38+
3939
/// <summary>Version, but if "", returns Build</summary>
4040
public static readonly string VersionOrBuild = GetVersionOrBuild();
4141

42-
static string GetRevision(string fileName)
43-
{
44-
try
45-
{
46-
using (var f = new StreamReader(Path.Combine(ApplicationPath, fileName)))
47-
{
48-
var revision = f.ReadLine().Trim();
49-
if (revision.StartsWith("$Revision:") && revision.EndsWith("$") && !revision.Contains(" 000 "))
50-
return revision.Substring(10, revision.Length - 11).Trim();
51-
}
52-
}
53-
catch
54-
{
55-
}
56-
return "";
57-
}
58-
5942
static string GetVersion(string fileName)
6043
{
6144
try
6245
{
63-
using (var f = new StreamReader(Path.Combine(ApplicationPath, fileName)))
64-
{
65-
var version = f.ReadLine().Trim();
66-
if (!String.IsNullOrEmpty(Revision))
67-
return version + Revision;
68-
}
46+
var version = FileVersionInfo.GetVersionInfo(Path.Combine(ApplicationPath, fileName));
47+
if (version.ProductVersion != version.FileVersion)
48+
return version.ProductVersion;
6949
}
7050
catch
7151
{
7252
}
7353
return "";
7454
}
7555

76-
static string GetBuild(params string[] fileNames)
56+
static string GetBuild(string fileName)
7757
{
7858
var builds = new Dictionary<TimeSpan, string>();
79-
foreach (var fileName in fileNames)
59+
try
8060
{
81-
try
82-
{
83-
var version = FileVersionInfo.GetVersionInfo(Path.Combine(ApplicationPath, fileName));
84-
builds.Add(new TimeSpan(version.ProductBuildPart, 0, 0, version.ProductPrivatePart * 2), version.ProductVersion);
85-
}
86-
catch
87-
{
88-
}
61+
var version = FileVersionInfo.GetVersionInfo(Path.Combine(ApplicationPath, fileName));
62+
var datetime = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc);
63+
var timespan = new TimeSpan(version.FileBuildPart, 0, 0, version.FilePrivatePart * 2);
64+
return String.Format("{0} ({1:u})", version.FileVersion, datetime + timespan);
8965
}
90-
if (builds.Count > 0)
66+
catch
9167
{
92-
var datetime = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc);
93-
var timespan = builds.Keys.OrderBy(ts => ts).Last();
94-
return String.Format("{0} ({1:u})", builds[timespan], datetime + timespan);
9568
}
9669
return "";
9770
}
@@ -102,70 +75,62 @@ static string GetVersionOrBuild()
10275
}
10376

10477
/// <summary>
105-
/// Find whether a requested version and build are valid for this build
78+
/// Compares a version and build with the youngest version which failed to restore, to see if that version/build is likely to restore successfully
10679
/// </summary>
107-
/// <param name="version">version to test again</param>
108-
/// <param name="build">build to test again</param>
109-
/// <param name="youngestFailedToResume">youngest build that failed to resume</param>
80+
/// <param name="version">version to test</param>
81+
/// <param name="build">build to test</param>
82+
/// <param name="youngestVersionFailedToRestore">youngest version that failed to restore</param>
11083
/// <returns>true or false when able to determine validity, null otherwise</returns>
111-
public static bool? GetValidity(string version, string build, int youngestFailedToResume)
84+
public static bool? GetValidity(string version, string build, string youngestVersionFailedToRestore)
11285
{
113-
int revision = GetRevisionFromVersion(version);
114-
int programRevision = 0;
115-
try // as Convert.ToInt32() can fail and version may be ""
116-
{
117-
programRevision = Convert.ToInt32(VersionInfo.Revision);
118-
}
119-
catch { } // ignore errors
120-
//MessageBox.Show(String.Format("VersionInfo.Build = {0}, build = {1}, version = {2}, youngestFailedToResume = {3}", VersionInfo.Build, build, Version, youngestFailedToResume));
121-
if (revision != 0) // compiled remotely by Open Rails
122-
{
123-
if (revision == programRevision)
124-
{
125-
return true;
126-
}
127-
else
128-
{
129-
if (revision > youngestFailedToResume // 1. Normal situation
130-
|| programRevision < youngestFailedToResume) // 2. If an old version of OR is used, then attempt to load Saves
131-
// which would be blocked by the current version of OR
132-
{
133-
return null;
134-
}
135-
}
136-
}
137-
else // compiled locally
138-
{
139-
if (build.EndsWith(VersionInfo.Build))
140-
{
141-
return true;
142-
}
143-
else
144-
{
145-
return null;
146-
}
147-
}
148-
return false; // default validity
86+
// Validity rules:
87+
// - Same version and build --> yes
88+
// - Same non-empty version --> yes
89+
// - Unable to parse save or program version --> maybe
90+
// - Save version > setting --> maybe
91+
// - Program version < setting --> maybe
92+
// - Default --> no
93+
94+
if (Version == version && Build == build) return true;
95+
if (Version.Length > 0 && version.Length > 0 && Version == version) return true;
96+
var saveVersion = ParseVersion(version);
97+
var programVersion = ParseVersion(Version);
98+
var settingVersion = ParseVersion(youngestVersionFailedToRestore);
99+
if (saveVersion.Major == 0 || programVersion.Major == 0) return null;
100+
if (saveVersion > settingVersion) return null;
101+
if (programVersion < settingVersion) return null;
102+
return false;
149103
}
150104

151105
/// <summary>
152-
/// Find the revision number (e.g. 1648) from the full version (e.g. 0.9.0.1648 or X.1648 or X1648)
106+
/// Converts many possible Open Rails versions into a standard Version struct
153107
/// </summary>
154-
/// <param name="version">full version</param>
155-
public static int GetRevisionFromVersion(string fullVersion)
108+
/// <param name="version">text version to parse</param>
109+
public static Version ParseVersion(string version)
156110
{
157-
var versionParts = fullVersion.Split('.');
158-
var revision = 0;
159-
try
160-
{
161-
var version = versionParts[versionParts.Length - 1];
162-
if (version.StartsWith("X"))
163-
version = version.Substring(1);
164-
// Might throw an error if it isn't a number like we expect.
165-
revision = Convert.ToInt32(version);
166-
}
167-
catch { }
168-
return revision;
111+
// Version numbers which we do parse:
112+
// - 0.9.0.1648 --> 0.9
113+
// - 1.3.1.4328 --> 1.3.1
114+
// - T1.3.1-241-g6ff150c21 --> 1.3.1.241
115+
// - X1.3.1-370-g7df5318c2 --> 1.3.1.370
116+
// - 1.4 --> 1.4
117+
// - 1.4-rc1 --> 1.4
118+
// - T1.4-2-g7db094316 --> 1.4.0.2
119+
// Version numbers which we do NOT parse:
120+
// - U2019.07.25-2200
121+
// - U2021.06.25-0406
122+
// - X.1648
123+
// - X1648
124+
125+
if (version.StartsWith("T") || version.StartsWith("X")) version = version.Substring(1);
126+
127+
var versionParts = version.Split('-');
128+
if (!System.Version.TryParse(versionParts[0], out var parsedVersion)) return new Version();
129+
130+
var commits = 0;
131+
if (versionParts.Length > 1) int.TryParse(versionParts[1], out commits);
132+
// parsedVersion.Build will be -1 if the version only has major and minor, but we need the build number >= 0 here
133+
return new Version(parsedVersion.Major, parsedVersion.Minor, Math.Max(0, parsedVersion.Build), commits);
169134
}
170135
}
171136
}

Source/ORTS.Settings/UserSettings.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,8 +380,8 @@ public enum DirectXFeature
380380
public string AvatarURL { get; set; }
381381
[Default(false)]
382382
public bool ShowAvatar { get; set; }
383-
[Default(0)] // Do not offer to restore/resume any saves this age or older. Updated whenever a younger save fails to restore.
384-
public int YoungestFailedToRestore { get; set; }
383+
[Default("0.0")] // Do not offer to restore/resume any saves this version or older. Updated whenever a younger save fails to restore.
384+
public string YoungestVersionFailedToRestore { get; set; }
385385

386386
// Internal settings:
387387
[Default(false)]

0 commit comments

Comments
 (0)