Skip to content

Commit

Permalink
Merge #4026 Prompt for client upgrade when newer spec is found
Browse files Browse the repository at this point in the history
  • Loading branch information
HebaruSan committed Feb 14, 2024
2 parents 2271c36 + b54c248 commit 6c5bf1f
Show file tree
Hide file tree
Showing 15 changed files with 64 additions and 41 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
- [GUI] Sort mods satisfying the same recommendation by download count (#4007 by: HebaruSan)
- [Multiple] Alternate game command lines and Steam refactor (#4010, #4013 by: HebaruSan)
- [Multiple] Recommendations usability improvements (#4025 by: HebaruSan)
- [Multiple] Prompt for client upgrade when newer spec is found (#4026 by: HebaruSan)

### Bugfixes

Expand Down
15 changes: 4 additions & 11 deletions Core/Meta.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using System.Linq;
using System.Reflection;

using CKAN.Versioning;

namespace CKAN
{
public static class Meta
Expand All @@ -16,6 +18,8 @@ public static string GetProductName()
.GetAssemblyAttribute<AssemblyProductAttribute>()
.Product;

public static readonly ModuleVersion ReleaseVersion = new ModuleVersion(GetVersion());

public static string GetVersion(VersionFormat format = VersionFormat.Normal)
{
var version = Assembly
Expand All @@ -25,8 +29,6 @@ public static string GetVersion(VersionFormat format = VersionFormat.Normal)

switch (format)
{
case VersionFormat.Short:
return $"v{version.UpToCharacters(shortDelimiters)}";
case VersionFormat.Normal:
return "v" + Assembly.GetExecutingAssembly()
.GetAssemblyAttribute<AssemblyFileVersionAttribute>()
Expand All @@ -38,15 +40,6 @@ public static string GetVersion(VersionFormat format = VersionFormat.Normal)
}
}

private static readonly char[] shortDelimiters = new char[] { '-', '+' };

private static string UpToCharacters(this string orig, char[] what)
=> orig.UpToIndex(orig.IndexOfAny(what));

private static string UpToIndex(this string orig, int index)
=> index == -1 ? orig
: orig.Substring(0, index);

private static T GetAssemblyAttribute<T>(this Assembly assembly)
=> (T)assembly.GetCustomAttributes(typeof(T), false)
.First();
Expand Down
31 changes: 22 additions & 9 deletions Core/Repositories/RepositoryData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ namespace CKAN
using ArchiveList = Tuple<List<CkanModule>,
SortedDictionary<string, int>,
GameVersion[],
Repository[]>;
Repository[],
bool>;

/// <summary>
/// Represents everything we retrieve from one metadata repository
Expand Down Expand Up @@ -63,6 +64,12 @@ public class RepositoryData
[JsonProperty("repositories", NullValueHandling = NullValueHandling.Ignore)]
public readonly Repository[] Repositories;

/// <summary>
/// true if any module we found requires a newer client version, false otherwise
/// </summary>
[JsonIgnore]
public readonly bool UnsupportedSpec;

private RepositoryData(Dictionary<string, AvailableModule> modules,
SortedDictionary<string, int> counts,
GameVersion[] versions,
Expand All @@ -84,14 +91,16 @@ private RepositoryData(Dictionary<string, AvailableModule> modules,
public RepositoryData(IEnumerable<CkanModule> modules,
SortedDictionary<string, int> counts,
IEnumerable<GameVersion> versions,
IEnumerable<Repository> repos)
IEnumerable<Repository> repos,
bool unsupportedSpec)
: this(modules?.GroupBy(m => m.identifier)
.ToDictionary(grp => grp.Key,
grp => new AvailableModule(grp.Key, grp)),
counts ?? new SortedDictionary<string, int>(),
(versions ?? Enumerable.Empty<GameVersion>()).ToArray(),
(repos ?? Enumerable.Empty<Repository>()).ToArray())
{
UnsupportedSpec = unsupportedSpec;
}

[JsonConstructor]
Expand Down Expand Up @@ -192,8 +201,9 @@ private static RepositoryData FromTarGz(string path, IGame game, IProgress<long>
(List<CkanModule> modules,
SortedDictionary<string, int> counts,
GameVersion[] versions,
Repository[] repos) = AggregateArchiveEntries(archiveEntriesFromTar(tarStream, game));
return new RepositoryData(modules, counts, versions, repos);
Repository[] repos,
bool unsupSpec) = AggregateArchiveEntries(archiveEntriesFromTar(tarStream, game));
return new RepositoryData(modules, counts, versions, repos, unsupSpec);
}
}

Expand Down Expand Up @@ -249,9 +259,10 @@ private static RepositoryData FromZip(string path, IGame game, IProgress<long> p
(List<CkanModule> modules,
SortedDictionary<string, int> counts,
GameVersion[] versions,
Repository[] repos) = AggregateArchiveEntries(archiveEntriesFromZip(zipfile, game));
Repository[] repos,
bool unsupSpec) = AggregateArchiveEntries(archiveEntriesFromZip(zipfile, game));
zipfile.Close();
return new RepositoryData(modules, counts, versions, repos);
return new RepositoryData(modules, counts, versions, repos, unsupSpec);
}
}

Expand All @@ -266,7 +277,7 @@ private static ParallelQuery<ArchiveEntry> archiveEntriesFromZip(ZipFile zipfile
entry.Offset));

private static ArchiveList AggregateArchiveEntries(ParallelQuery<ArchiveEntry> entries)
=> entries.Aggregate(new ArchiveList(new List<CkanModule>(), null, null, null),
=> entries.Aggregate(new ArchiveList(new List<CkanModule>(), null, null, null, false),
(subtotal, item) =>
item == null
? subtotal
Expand All @@ -276,12 +287,14 @@ private static ArchiveList AggregateArchiveEntries(ParallelQuery<ArchiveEntry> e
: subtotal.Item1.Append(item.Item1).ToList(),
subtotal.Item2 ?? item.Item2,
subtotal.Item3 ?? item.Item3,
subtotal.Item4 ?? item.Item4),
subtotal.Item4 ?? item.Item4,
subtotal.Item5 || item.Item1 == null),
(total, subtotal)
=> new ArchiveList(total.Item1.Concat(subtotal.Item1).ToList(),
total.Item2 ?? subtotal.Item2,
total.Item3 ?? subtotal.Item3,
total.Item4 ?? subtotal.Item4),
total.Item4 ?? subtotal.Item4,
total.Item5 || subtotal.Item5),
total => total);

private static ArchiveEntry getArchiveEntry(string filename,
Expand Down
5 changes: 4 additions & 1 deletion Core/Repositories/RepositoryDataManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ public enum UpdateResult
Failed,
Updated,
NoChanges,
OutdatedClient,
}

/// <summary>
Expand Down Expand Up @@ -218,7 +219,9 @@ public UpdateResult Update(Repository[] repos,
downloader.onOneCompleted -= setETag;
}

return UpdateResult.Updated;
return repositoriesData.Values.Any(repoData => repoData.UnsupportedSpec)
? UpdateResult.OutdatedClient
: UpdateResult.Updated;
}

/// <summary>
Expand Down
7 changes: 1 addition & 6 deletions Core/Types/CkanModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -700,12 +700,7 @@ bool IEquatable<CkanModule>.Equals(CkanModule other)
/// Returns true if we support at least spec_version of the CKAN spec.
/// </summary>
internal static bool IsSpecSupported(ModuleVersion spec_version)
{
// This could be a read-only state variable; do we have those in C#?
ModuleVersion release = new ModuleVersion(Meta.GetVersion(VersionFormat.Short));

return release == null || release.IsGreaterThan(spec_version);
}
=> Meta.ReleaseVersion.IsGreaterThan(spec_version);

/// <summary>
/// Returns true if we support the CKAN spec used by this module.
Expand Down
2 changes: 1 addition & 1 deletion Core/Types/ModuleInstallDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ private void EnsurePattern()
}
else
{
throw new UnsupportedKraken(Properties.Resources.ModuleInstallDescriptorRequireFileFind);
throw new Kraken(Properties.Resources.ModuleInstallDescriptorRequireFileFind);
}
}
}
Expand Down
1 change: 0 additions & 1 deletion Core/VersionFormat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ namespace CKAN
{
public enum VersionFormat
{
Short,
Normal,
Full
}
Expand Down
2 changes: 1 addition & 1 deletion GUI/Dialogs/NewUpdateDialog.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion GUI/Dialogs/NewUpdateDialog.resx
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="label1.Text" xml:space="preserve"><value>Version:</value></data>
<data name="VersionLabel.Text" xml:space="preserve"><value>v0.0.0</value></data>
<data name="InstallUpdateButton.Text" xml:space="preserve"><value>Install</value></data>
<data name="CancelUpdateButton.Text" xml:space="preserve"><value>Not now</value></data>
<data name="$this.Text" xml:space="preserve"><value>A new version of CKAN is available</value></data>
Expand Down
2 changes: 1 addition & 1 deletion GUI/Dialogs/SettingsDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ private void CheckForUpdatesButton_Click(object sender, EventArgs e)

private void InstallUpdateButton_Click(object sender, EventArgs e)
{
if (AutoUpdate.CanUpdate)
if (Main.Instance.CheckForCKANUpdate())
{
Hide();
Main.Instance.UpdateCKAN();
Expand Down
7 changes: 6 additions & 1 deletion GUI/Main/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,12 @@ private void CurrentInstanceUpdated()
.Resolve<IConfiguration>(),
configuration);

bool autoUpdating = CheckForCKANUpdate();
bool autoUpdating = configuration.CheckForUpdatesOnLaunch
&& CheckForCKANUpdate();
if (autoUpdating)
{
UpdateCKAN();
}

var pluginsPath = Path.Combine(CurrentInstance.CkanDir(), "Plugins");
if (!Directory.Exists(pluginsPath))
Expand Down
12 changes: 5 additions & 7 deletions GUI/Main/MainAutoUpdate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,26 +42,24 @@ private void AutoUpdatePrompts(IConfiguration coreConfig,
/// <returns>
/// true if update found, false otherwise.
/// </returns>
private bool CheckForCKANUpdate()
public bool CheckForCKANUpdate()
{
if (configuration.CheckForUpdatesOnLaunch && AutoUpdate.CanUpdate)
if (AutoUpdate.CanUpdate)
{
try
{
log.Info("Making auto-update call");
var mainConfig = ServiceLocator.Container.Resolve<IConfiguration>();
var update = updater.GetUpdate(mainConfig.DevBuilds ?? false);
var latestVersion = update.Version;
var currentVersion = new ModuleVersion(Meta.GetVersion());

if (latestVersion.IsGreaterThan(currentVersion))
if (latestVersion.IsGreaterThan(Meta.ReleaseVersion))
{
log.Debug("Found higher ckan version");
log.DebugFormat("Found higher CKAN version: {0}", latestVersion);
var releaseNotes = update.ReleaseNotes;
var dialog = new NewUpdateDialog(latestVersion.ToString(), releaseNotes);
if (dialog.ShowDialog(this) == DialogResult.OK)
{
UpdateCKAN();
return true;
}
}
Expand Down Expand Up @@ -90,7 +88,7 @@ public void UpdateCKAN()
Wait.SetDescription(string.Format(Properties.Resources.MainUpgradingTo,
update.Version));

log.Info("Start ckan update");
log.Info("Starting CKAN update");
Wait.StartWaiting((sender, args) => updater.StartUpdateProcess(true, mainConfig.DevBuilds ?? false, currentUser),
UpdateReady,
false,
Expand Down
16 changes: 16 additions & 0 deletions GUI/Main/MainRepo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,22 @@ private void PostUpdateRepo(object sender, RunWorkerCompletedEventArgs e)
}
break;


case RepositoryDataManager.UpdateResult.OutdatedClient:
currentUser.RaiseMessage(Properties.Resources.MainRepoOutdatedClient);
if (CheckForCKANUpdate())
{
UpdateCKAN();
}
else
{
// No update available or user said no. Proceed as normal.
ShowRefreshQuestion();
UpgradeNotification();
RefreshModList(false, oldModules);
}
break;

case RepositoryDataManager.UpdateResult.Updated:
default:
currentUser.RaiseMessage(Properties.Resources.MainRepoSuccess);
Expand Down
1 change: 1 addition & 0 deletions GUI/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ If you suspect a bug in the client: https://github.com/KSP-CKAN/CKAN/issues/new/
<data name="MainRepoUpToDate" xml:space="preserve"><value>Repositories already up to date.</value></data>
<data name="MainRepoFailed" xml:space="preserve"><value>Repository update failed!</value></data>
<data name="MainRepoSuccess" xml:space="preserve"><value>Repositories successfully updated.</value></data>
<data name="MainRepoOutdatedClient" xml:space="preserve"><value>Repositories updated, but found modules that require a new version of CKAN. Checking for updates...</value></data>
<data name="MainRepoAutoRefreshPrompt" xml:space="preserve"><value>Would you like CKAN to refresh the modlist every time it is loaded? (You can always manually refresh using the button up top.)</value></data>
<data name="MainRepoBalloonTipDetails" xml:space="preserve"><value>{0} update(s) available</value></data>
<data name="MainRepoBalloonTipTooltip" xml:space="preserve"><value>Click to upgrade</value></data>
Expand Down
2 changes: 1 addition & 1 deletion GlobalAssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[assembly: AssemblyProduct("CKAN")]
[assembly: AssemblyCompany("CKAN Contributors")]
[assembly: AssemblyCopyright("Copyright © 2014–2023")]
[assembly: AssemblyCopyright("Copyright © 2014–2024")]

#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
Expand Down

0 comments on commit 6c5bf1f

Please sign in to comment.