Skip to content

Commit

Permalink
#26: Fixed resolution of latest build to depend only on version number
Browse files Browse the repository at this point in the history
  • Loading branch information
jirkapok committed Jun 15, 2017
1 parent 665ede8 commit 81d59b0
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 52 deletions.
2 changes: 1 addition & 1 deletion Source/Terminals/Updates/Release.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Terminals.Updates
public class Release
{
[JsonProperty("tag_name")]
public string TagName { get; set; }
public Version Version { get; set; }

[JsonProperty("name")]

Expand Down
46 changes: 13 additions & 33 deletions Source/Terminals/Updates/UpdateManager.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Terminals.Properties;
Expand Down Expand Up @@ -37,12 +36,12 @@ private static string DownloadReleases()
/// </summary>
internal Task<ReleaseInfo> CheckForUpdates(bool automaticallyUpdate)
{
return Task<ReleaseInfo>.Factory.StartNew((autoUpdate) => this.PerformCheck((bool)autoUpdate), automaticallyUpdate);
return Task<ReleaseInfo>.Factory.StartNew(autoUpdate => this.PerformCheck((bool)autoUpdate), automaticallyUpdate);
}

private ReleaseInfo PerformCheck(bool automaticallyUpdate)
{
ReleaseInfo downLoaded = this.CheckForCodeplexRelease(Program.Info.BuildDate);
ReleaseInfo downLoaded = this.CheckForCodeplexRelease(Program.Info.Version);

// todo the automatic updates point to wrong URL this feature is not working
bool autoUpdate = automaticallyUpdate; // obtain from command line arguments
Expand All @@ -54,15 +53,15 @@ private ReleaseInfo PerformCheck(bool automaticallyUpdate)
return downLoaded;
}

internal ReleaseInfo CheckForCodeplexRelease(DateTime buildDate)
internal ReleaseInfo CheckForCodeplexRelease(Version currentVersion)
{
try
{
return this.TryCheckForCodeplexRelease(buildDate);
return this.TryCheckForPublishedRelease(currentVersion);
}
catch (Exception exception)
{
Logging.Error("Failed during CheckForCodeplexRelease.", exception);
Logging.Error("Failed during Check for release.", exception);
return ReleaseInfo.NotAvailable;
}
}
Expand All @@ -72,56 +71,37 @@ internal ReleaseInfo CheckForCodeplexRelease(DateTime buildDate)
/// Returns not null info about obtained current release.
/// ReleaseInfo.NotAvailable in a case, new version was not checked or current version is the latest.
/// </summary>
private ReleaseInfo TryCheckForCodeplexRelease(DateTime buildDate)
private ReleaseInfo TryCheckForPublishedRelease(Version currentVersion)
{
var checksFile = new UpdateChecksFile();
if (!checksFile.ShouldCheckForUpdate)
return ReleaseInfo.NotAvailable;

ReleaseInfo downLoaded = this.DownLoadLatestReleaseInfo(buildDate);
ReleaseInfo downLoaded = this.DownLoadLatestReleaseInfo(currentVersion);
checksFile.WriteLastCheck();
return downLoaded;
}

private ReleaseInfo DownLoadLatestReleaseInfo(DateTime buildDate)
private ReleaseInfo DownLoadLatestReleaseInfo(Version currentVersion)
{
string downloaded = this.readReleases();
Release[] feed = JsonConvert.DeserializeObject<Release[]>(downloaded);

if (feed != null)
{
Release newvestRssItem = SelectNewvestRssItem(feed, buildDate);
Release newvestRssItem = SelectNewvestRssItem(feed, currentVersion);
if (newvestRssItem != null)
return new ReleaseInfo(newvestRssItem.Published, newvestRssItem.TagName);
return new ReleaseInfo(newvestRssItem.Published, newvestRssItem.Version.ToString());
}

return ReleaseInfo.NotAvailable;
}

private static Release SelectNewvestRssItem(Release[] feed, DateTime buildDate)
private static Release SelectNewvestRssItem(Release[] feed, Version currentVersion)
{
return feed.Where(item => IsNewerThanCurrent(item, buildDate))
.OrderByDescending(selected => selected.Published)
return feed.Where(item => item.Version > currentVersion)
.OrderByDescending(selected => selected.Version)
.FirstOrDefault();
}

/// <summary>
/// Inteligent resolution of latest build by real "release date", not only by the date used to publish the feed.
/// This filters the updates on release page after the release was published.
/// Obtains the real date from the title.
/// </summary>
private static bool IsNewerThanCurrent(Release item, DateTime buildDate)
{
// rss item published date
if (item.Published < buildDate)
return false;

const string DATE_FILTER = @"([^\(]+)\((?<Date>[^\(\)]+)\)"; // Select string iside brackets as "Date" group
string titleDate = Regex.Match(item.Name, DATE_FILTER).Groups["Date"].Value;
DateTime releaseDate;
// there is no culture specification when downloading the feed, so it is always EN
DateTime.TryParse(titleDate, out releaseDate);
return releaseDate > buildDate;
}
}
}
30 changes: 12 additions & 18 deletions Source/Tests/UpdateManagerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Globalization;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Terminals;
using Terminals.Configuration;
using Terminals.Updates;
using Tests.FilePersisted;
Expand All @@ -13,13 +12,13 @@ namespace Tests
/// Check for new release to be able parse release rss feeds, to be able to download and unpack the update package.
/// Expected implementation of UpdateManager:
/// - the update check file is written after all checks
/// - release shouldn't be reported only, if there is a release with newer build date, than current
/// - release shouldn't be reported only, if there is a release with newer version, than current
/// - new release should be reported once per day only
/// </summary>
[TestClass]
public class UpdateManagerTest
{
private DateTime buildDate = Program.Info.BuildDate;
private Version currentVersion = new Version(2, 0, 0);

private readonly DateTime yesterDay = DateTime.Today.AddDays(-1);

Expand All @@ -38,6 +37,7 @@ public void ConfigureTestLab()
[TestMethod]
public void CurrentBuild_CheckForCodeplexRelease_ReturnsNotAvailable()
{
this.currentVersion = new Version(4, 0, 0);
ReleaseInfo checkResult = this.RunUpdateCheck();

Assert.AreEqual(ReleaseInfo.NotAvailable, checkResult, "New release noticed");
Expand All @@ -47,7 +47,7 @@ public void CurrentBuild_CheckForCodeplexRelease_ReturnsNotAvailable()
[TestMethod]
public void OldestBuildDate_CheckForCodeplexRelease_ReturnsValidRelease()
{
this.buildDate = DateTime.MinValue;
this.currentVersion = new Version(1, 0, 0);
ReleaseInfo checkResult = this.RunUpdateCheck();

Assert.AreNotEqual(ReleaseInfo.NotAvailable, checkResult, "Didn't notice new release");
Expand All @@ -68,23 +68,17 @@ public void TodayCheckedDate_CheckForCodeplexRelease_DoesnotUpdateCheckDate()

private ReleaseInfo RunUpdateCheck()
{
var updateManager = new UpdateManager(this.CreateRss);
return updateManager.CheckForCodeplexRelease(this.buildDate);
}

private string CreateRss()
{
const string downloaded = @"
const string CreateRss = @"
[
{{
""name"": ""Title({0})"",
""tag_name"": ""1.0.0"",
""published_at"": ""{0}""
}}
{
""name"": ""Title"",
""tag_name"": ""3.0.0"",
""published_at"": ""2017-06-14T20:25:15Z""
}
]";
DateTime currentRelease = new DateTime(2010, 1, 3, 1, 0, 0, DateTimeKind.Utc);

return string.Format(downloaded, currentRelease);
var updateManager = new UpdateManager(() => CreateRss);
return updateManager.CheckForCodeplexRelease(this.currentVersion);
}

private void AssertLastUpdateCheck()
Expand Down

0 comments on commit 81d59b0

Please sign in to comment.