Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update SUVersionDisplay to allow including build versions and update information #2321

Merged
merged 5 commits into from
Feb 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion Sparkle.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,10 @@
72AC6B2A1B9AAF3A00F62325 /* SparkleTestCodeSignApp.tar.bz2 in Resources */ = {isa = PBXBuildFile; fileRef = 72AC6B291B9AAF3A00F62325 /* SparkleTestCodeSignApp.tar.bz2 */; };
72AC6B2C1B9AB0EE00F62325 /* SparkleTestCodeSignApp.tar.xz in Resources */ = {isa = PBXBuildFile; fileRef = 72AC6B2B1B9AB0EE00F62325 /* SparkleTestCodeSignApp.tar.xz */; };
72AC6B2E1B9B218C00F62325 /* SparkleTestCodeSignApp.dmg in Resources */ = {isa = PBXBuildFile; fileRef = 72AC6B2D1B9B218C00F62325 /* SparkleTestCodeSignApp.dmg */; };
72AEB1D429A1A74E0033883E /* SPUStandardVersionDisplay.h in Headers */ = {isa = PBXBuildFile; fileRef = 72AEB1D229A1A74E0033883E /* SPUStandardVersionDisplay.h */; };
72AEB1D529A1A74E0033883E /* SPUStandardVersionDisplay.m in Sources */ = {isa = PBXBuildFile; fileRef = 72AEB1D329A1A74E0033883E /* SPUStandardVersionDisplay.m */; };
72AEB1D829A1CB510033883E /* SPUNoUpdateFoundInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 72AEB1D629A1CB510033883E /* SPUNoUpdateFoundInfo.h */; };
72AEB1D929A1CB510033883E /* SPUNoUpdateFoundInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 72AEB1D729A1CB510033883E /* SPUNoUpdateFoundInfo.m */; };
72B3DEC91E23472200457642 /* SPUDownloadedUpdate.h in Headers */ = {isa = PBXBuildFile; fileRef = 72B3DEC71E23472200457642 /* SPUDownloadedUpdate.h */; };
72B3DECA1E23472200457642 /* SPUDownloadedUpdate.m in Sources */ = {isa = PBXBuildFile; fileRef = 72B3DEC81E23472200457642 /* SPUDownloadedUpdate.m */; };
72B3DECD1E23479000457642 /* SPUInformationalUpdate.h in Headers */ = {isa = PBXBuildFile; fileRef = 72B3DECB1E23479000457642 /* SPUInformationalUpdate.h */; };
Expand Down Expand Up @@ -1342,6 +1346,10 @@
72AC6B291B9AAF3A00F62325 /* SparkleTestCodeSignApp.tar.bz2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = SparkleTestCodeSignApp.tar.bz2; sourceTree = "<group>"; };
72AC6B2B1B9AB0EE00F62325 /* SparkleTestCodeSignApp.tar.xz */ = {isa = PBXFileReference; lastKnownFileType = file; path = SparkleTestCodeSignApp.tar.xz; sourceTree = "<group>"; };
72AC6B2D1B9B218C00F62325 /* SparkleTestCodeSignApp.dmg */ = {isa = PBXFileReference; lastKnownFileType = file; path = SparkleTestCodeSignApp.dmg; sourceTree = "<group>"; };
72AEB1D229A1A74E0033883E /* SPUStandardVersionDisplay.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SPUStandardVersionDisplay.h; sourceTree = "<group>"; };
72AEB1D329A1A74E0033883E /* SPUStandardVersionDisplay.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SPUStandardVersionDisplay.m; sourceTree = "<group>"; };
72AEB1D629A1CB510033883E /* SPUNoUpdateFoundInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SPUNoUpdateFoundInfo.h; sourceTree = "<group>"; };
72AEB1D729A1CB510033883E /* SPUNoUpdateFoundInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SPUNoUpdateFoundInfo.m; sourceTree = "<group>"; };
72AFC6121B9A944200F6B565 /* Sparkle Unit Tests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Sparkle Unit Tests-Bridging-Header.h"; sourceTree = "<group>"; };
72B09CE91CEA18900052EF9E /* bscommon.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bscommon.c; sourceTree = "<group>"; };
72B09CEA1CEA18900052EF9E /* bscommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bscommon.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1975,7 +1983,6 @@
612DCBAE0D488BC60015DBEA /* SUUpdatePermissionPrompt.m */,
723C8A521E2D60DB00C14942 /* SUTouchBarButtonGroup.h */,
723C8A531E2D60DB00C14942 /* SUTouchBarButtonGroup.m */,
3772FEA813DE0B6B00F79537 /* SUVersionDisplayProtocol.h */,
);
name = "User Interface";
sourceTree = "<group>";
Expand Down Expand Up @@ -2026,6 +2033,11 @@
727F340A2605321D00020E85 /* SULog+NSError.m */,
726F2CE31BC9C33D001971A4 /* SUOperatingSystem.h */,
726F2CE41BC9C33D001971A4 /* SUOperatingSystem.m */,
3772FEA813DE0B6B00F79537 /* SUVersionDisplayProtocol.h */,
72AEB1D229A1A74E0033883E /* SPUStandardVersionDisplay.h */,
72AEB1D329A1A74E0033883E /* SPUStandardVersionDisplay.m */,
72AEB1D629A1CB510033883E /* SPUNoUpdateFoundInfo.h */,
72AEB1D729A1CB510033883E /* SPUNoUpdateFoundInfo.m */,
);
includeInIndex = 1;
name = "Other Sources";
Expand Down Expand Up @@ -2485,6 +2497,7 @@
72B767E21C9CE90A00A07552 /* SPUCoreBasedUpdateDriver.h in Headers */,
72F9EC441D5E9ED8004AC8B6 /* SPUDownloadData.h in Headers */,
72EF30C12675CF38008CE987 /* SPUAppcastItemState.h in Headers */,
72AEB1D429A1A74E0033883E /* SPUStandardVersionDisplay.h in Headers */,
7229E1BD1C98EFF200CB50D0 /* SPUDownloadDriver.h in Headers */,
7267E5FD1D3DD1B700D1BF90 /* SPUResumableUpdate.h in Headers */,
7267E5B61D3D8AEE00D1BF90 /* SPUInstallationInfo.h in Headers */,
Expand Down Expand Up @@ -2521,6 +2534,7 @@
72F9EC3F1D5E823F004AC8B6 /* SPUUpdaterTimer.h in Headers */,
7269E494264798200088C213 /* SPUSkippedUpdate.h in Headers */,
723ABFC4259D4CB300BDB4FA /* SUWKWebView.h in Headers */,
72AEB1D829A1CB510033883E /* SPUNoUpdateFoundInfo.h in Headers */,
725CB9571C7120410064365A /* SPUUserDriver.h in Headers */,
72B767DE1C9CDB9700A07552 /* SPUUserInitiatedUpdateDriver.h in Headers */,
72F94F581CC44DE1002DEE68 /* SPUXPCServiceInfo.h in Headers */,
Expand Down Expand Up @@ -3587,6 +3601,7 @@
72EF30C02675CF38008CE987 /* SPUAppcastItemStateResolver.m in Sources */,
61B5F8EE09C4CE3C00B25A18 /* SPUUpdater.m in Sources */,
720E217C1D0D00BF003A311C /* SPUUpdaterCycle.m in Sources */,
72AEB1D529A1A74E0033883E /* SPUStandardVersionDisplay.m in Sources */,
726E078E1CA891E9001A286B /* SPUUpdaterSettings.m in Sources */,
721D588F25BE59F900D23BEA /* SUPhasedUpdateGroupInfo.m in Sources */,
72F9EC401D5E823F004AC8B6 /* SPUUpdaterTimer.m in Sources */,
Expand Down Expand Up @@ -3614,6 +3629,7 @@
7286EE6028CEC84900163C1D /* SUPlainTextReleaseNotesView.m in Sources */,
6196CFFA09C72149000DC222 /* SUStatusController.m in Sources */,
72B3DECA1E23472200457642 /* SPUDownloadedUpdate.m in Sources */,
72AEB1D929A1CB510033883E /* SPUNoUpdateFoundInfo.m in Sources */,
61A2279D0D1CEE7600430CCD /* SUSystemProfiler.m in Sources */,
61B5FCDE09C52A9F00B25A18 /* SUUpdateAlert.m in Sources */,
612DCBB00D488BC60015DBEA /* SUUpdatePermissionPrompt.m in Sources */,
Expand Down
22 changes: 10 additions & 12 deletions Sparkle/SPUBasicUpdateDriver.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
#import "SPUAppcastItemState.h"
#import "SUAppcastItem+Private.h"
#import "SPUInstallationType.h"
#import "SUVersionDisplayProtocol.h"
#import "SPUStandardVersionDisplay.h"
#import "SPUNoUpdateFoundInfo.h"


#include "AppKitPrevention.h"
Expand Down Expand Up @@ -184,10 +187,11 @@ - (void)didNotFindUpdateWithLatestAppcastItem:(nullable SUAppcastItem *)latestAp
{
if (!_aborted) {
NSString *localizedDescription;
NSString *recoverySuggestion;

#if SPARKLE_COPY_LOCALIZATIONS
NSBundle *sparkleBundle = SUSparkleBundle();
#else
NSBundle *sparkleBundle = nil;
#endif

SPUNoUpdateFoundReason reason;
Expand All @@ -197,16 +201,12 @@ - (void)didNotFindUpdateWithLatestAppcastItem:(nullable SUAppcastItem *)latestAp
// This means the user is a 'newer than latest' version. give a slight hint to the user instead of wrongly claiming this version is identical to the latest feed version.
localizedDescription = SULocalizedStringFromTableInBundle(@"You’re up-to-date!", SPARKLE_TABLE, sparkleBundle, "Status message shown when the user checks for updates but is already current or the feed doesn't contain any updates.");

recoverySuggestion = [NSString stringWithFormat:SULocalizedStringFromTableInBundle(@"%@ %@ is currently the newest version available.\n(You are currently running version %@.)", SPARKLE_TABLE, sparkleBundle, nil), [_host name], latestAppcastItem.displayVersionString, [_host displayVersion]];

reason = SPUNoUpdateFoundReasonOnNewerThanLatestVersion;
break;
case NSOrderedSame:
// No new update is available and we're on the latest
localizedDescription = SULocalizedStringFromTableInBundle(@"You’re up-to-date!", SPARKLE_TABLE, sparkleBundle, "Status message shown when the user checks for updates but is already current or the feed doesn't contain any updates.");

recoverySuggestion = [NSString stringWithFormat:SULocalizedStringFromTableInBundle(@"%@ %@ is currently the newest version available.", SPARKLE_TABLE, sparkleBundle, nil), [_host name], [_host displayVersion]];

reason = SPUNoUpdateFoundReasonOnLatestVersion;
break;
case NSOrderedAscending:
Expand All @@ -215,21 +215,15 @@ - (void)didNotFindUpdateWithLatestAppcastItem:(nullable SUAppcastItem *)latestAp
if (!latestAppcastItem.minimumOperatingSystemVersionIsOK) {
localizedDescription = SULocalizedStringFromTableInBundle(@"Your macOS version is too old", SPARKLE_TABLE, sparkleBundle, nil);

recoverySuggestion = [NSString stringWithFormat:SULocalizedStringFromTableInBundle(@"%1$@ %2$@ is available but your macOS version is too old to install it. At least macOS %3$@ is required.", SPARKLE_TABLE, sparkleBundle, nil), [_host name], latestAppcastItem.displayVersionString, latestAppcastItem.minimumSystemVersion];

reason = SPUNoUpdateFoundReasonSystemIsTooOld;
} else if (!latestAppcastItem.maximumOperatingSystemVersionIsOK) {
localizedDescription = SULocalizedStringFromTableInBundle(@"Your macOS version is too new", SPARKLE_TABLE, sparkleBundle, nil);

recoverySuggestion = [NSString stringWithFormat:SULocalizedStringFromTableInBundle(@"%1$@ %2$@ is available but your macOS version is too new for this update. This update only supports up to macOS %3$@.", SPARKLE_TABLE, sparkleBundle, nil), [_host name], latestAppcastItem.displayVersionString, latestAppcastItem.maximumSystemVersion];

reason = SPUNoUpdateFoundReasonSystemIsTooNew;
} else {
// We shouldn't realistically get here
localizedDescription = SULocalizedStringFromTableInBundle(@"You’re up-to-date!", SPARKLE_TABLE, sparkleBundle, "Status message shown when the user checks for updates but is already current or the feed doesn't contain any updates.");

recoverySuggestion = [NSString stringWithFormat:SULocalizedStringFromTableInBundle(@"%@ %@ is currently the newest version available.", SPARKLE_TABLE, sparkleBundle, nil), [_host name], [_host displayVersion]];

reason = SPUNoUpdateFoundReasonUnknown;
}
break;
Expand All @@ -240,11 +234,15 @@ - (void)didNotFindUpdateWithLatestAppcastItem:(nullable SUAppcastItem *)latestAp
// There could be update items on channels the updater is not subscribed to for example. But we can't tell the user about them.
// There could also only be update items available for other platforms or none at all.
localizedDescription = SULocalizedStringFromTableInBundle(@"You’re up-to-date!", SPARKLE_TABLE, sparkleBundle, "Status message shown when the user checks for updates but is already current or the feed doesn't contain any updates.");
recoverySuggestion = [NSString stringWithFormat:SULocalizedStringFromTableInBundle(@"%@ %@ is currently the newest version available.", SPARKLE_TABLE, sparkleBundle, nil), [_host name], [_host displayVersion]];

reason = SPUNoUpdateFoundReasonOnLatestVersion;
}

// We use the standard version displayer here to construct a reason string,
// but it's possible for the user driver to override this before displaying if they wish
id<SUVersionDisplay> versionDisplayer = [SPUStandardVersionDisplay standardVersionDisplay];
NSString *recoverySuggestion = SPUNoUpdateFoundRecoverySuggestion(reason, latestAppcastItem, _host, versionDisplayer, sparkleBundle);

NSString *recoveryOption = SULocalizedStringFromTableInBundle(@"OK", SPARKLE_TABLE, sparkleBundle, nil);

NSMutableDictionary *userInfo =
Expand Down
21 changes: 21 additions & 0 deletions Sparkle/SPUNoUpdateFoundInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// SPUNoUpdateFoundInfo.h
// Sparkle
//
// Created on 2/18/23.
// Copyright © 2023 Sparkle Project. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "SUVersionDisplayProtocol.h"
#import "SUErrors.h"

@class SUAppcastItem;
@class SUHost;

NS_ASSUME_NONNULL_BEGIN

NSString *SPUNoUpdateFoundRecoverySuggestion(SPUNoUpdateFoundReason reason, SUAppcastItem * _Nullable latestAppcastItem, SUHost *host, id<SUVersionDisplay> versionDisplayer, NSBundle * _Nullable sparkleBundle);

NS_ASSUME_NONNULL_END
73 changes: 73 additions & 0 deletions Sparkle/SPUNoUpdateFoundInfo.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// SPUNoUpdateFoundInfo.m
// Sparkle
//
// Created on 2/18/23.
// Copyright © 2023 Sparkle Project. All rights reserved.
//

#import "SPUNoUpdateFoundInfo.h"
#import "SUAppcastItem.h"
#import "SUHost.h"
#import "SULocalizations.h"
#import "SUlog.h"


#include "AppKitPrevention.h"

NSString *SPUNoUpdateFoundRecoverySuggestion(SPUNoUpdateFoundReason reason, SUAppcastItem *latestAppcastItem, SUHost *host, id<SUVersionDisplay> versionDisplayer, NSBundle *sparkleBundle)
{
#if !SPARKLE_COPY_LOCALIZATIONS
(void)sparkleBundle;
#endif

NSString *hostDisplayVersion;
NSString *latestAppcastItemDisplayVersion;

switch (reason) {
case SPUNoUpdateFoundReasonUnknown:
case SPUNoUpdateFoundReasonOnLatestVersion:
if ([versionDisplayer respondsToSelector:@selector(formatBundleDisplayVersion:withBundleVersion:matchingUpdate:)]) {
hostDisplayVersion = [versionDisplayer formatBundleDisplayVersion:host.displayVersion withBundleVersion:host.version matchingUpdate:latestAppcastItem];
} else {
hostDisplayVersion = host.displayVersion;
}

// This is not later used
latestAppcastItemDisplayVersion = nil;
break;
case SPUNoUpdateFoundReasonOnNewerThanLatestVersion:
case SPUNoUpdateFoundReasonSystemIsTooOld:
case SPUNoUpdateFoundReasonSystemIsTooNew:
assert(latestAppcastItem != nil);

hostDisplayVersion = host.displayVersion;

if ([versionDisplayer respondsToSelector:@selector(formatUpdateDisplayVersionFromUpdate:andBundleDisplayVersion:withBundleVersion:)]) {
latestAppcastItemDisplayVersion = [versionDisplayer formatUpdateDisplayVersionFromUpdate:latestAppcastItem andBundleDisplayVersion:&hostDisplayVersion withBundleVersion:host.version];
} else {
// Legacy -formatVersion:andVersion: was never supported for this path so we don't need to call it
latestAppcastItemDisplayVersion = latestAppcastItem.displayVersionString;
}

break;
}

NSString *recoverySuggestion;
switch (reason) {
case SPUNoUpdateFoundReasonUnknown:
case SPUNoUpdateFoundReasonOnLatestVersion:
recoverySuggestion = [NSString stringWithFormat:SULocalizedStringFromTableInBundle(@"%@ %@ is currently the newest version available.", SPARKLE_TABLE, sparkleBundle, nil), host.name, hostDisplayVersion];
break;
case SPUNoUpdateFoundReasonOnNewerThanLatestVersion:
recoverySuggestion = [NSString stringWithFormat:SULocalizedStringFromTableInBundle(@"%@ %@ is currently the newest version available.\n(You are currently running version %@.)", SPARKLE_TABLE, sparkleBundle, nil), host.name, latestAppcastItemDisplayVersion, hostDisplayVersion];
break;
case SPUNoUpdateFoundReasonSystemIsTooOld:
recoverySuggestion = [NSString stringWithFormat:SULocalizedStringFromTableInBundle(@"%1$@ %2$@ is available but your macOS version is too old to install it. At least macOS %3$@ is required.", SPARKLE_TABLE, sparkleBundle, nil), host.name, latestAppcastItemDisplayVersion, latestAppcastItem.minimumSystemVersion];
break;
case SPUNoUpdateFoundReasonSystemIsTooNew:
recoverySuggestion = [NSString stringWithFormat:SULocalizedStringFromTableInBundle(@"%1$@ %2$@ is available but your macOS version is too new for this update. This update only supports up to macOS %3$@.", SPARKLE_TABLE, sparkleBundle, nil), host.name, latestAppcastItemDisplayVersion, latestAppcastItem.maximumSystemVersion];
break;
}
return recoverySuggestion;
}
Loading