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

Add support for extracting Apple Archives (.aar files) #2586

Merged
merged 2 commits into from
Jun 19, 2024
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
32 changes: 27 additions & 5 deletions Autoupdate/SUPipedUnarchiver.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ @implementation SUPipedUnarchiver
NSArray <NSString *> *extractTXZ = extractTGZ;

// Note: keep this list in sync with generate_appcast's unarchiveUpdates()
NSDictionary <NSString *, NSArray<NSString *> *> *extractCommandDictionary =
@{
NSMutableDictionary <NSString *, NSArray<NSString *> *> *extractCommandDictionary =
[@{
@".zip" : @[@"/usr/bin/ditto", @"-x",@"-k",@"-"],
@".tar" : @[@"/usr/bin/tar", @"-xC"],
@".tar.gz" : extractTGZ,
Expand All @@ -37,8 +37,28 @@ @implementation SUPipedUnarchiver
@".tbz" : extractTBZ,
@".tar.xz" : extractTXZ,
@".txz" : extractTXZ,
@".tar.lzma" : extractTXZ
};
@".tar.lzma" : extractTXZ,
} mutableCopy];

// At least the latest versions of 10.15 understand how to extract aar files
// Versions before 10.15 do not understand extracting newly created aar files
// Note encrypted aea files are supported in macOS 12 onwards, if we ever want to support those one day
if (@available(macOS 10.15.7, *)) {
NSString *appleArchiveCommand;
if (@available(macOS 11, *)) {
appleArchiveCommand = @"/usr/bin/aa";
} else {
// In 10.15 the utility was named yaa, which was later renamed to aar
appleArchiveCommand = @"/usr/bin/yaa";
}

NSArray <NSString *> *extractAppleArchive = @[appleArchiveCommand, @"extract", @"-d"];

[extractCommandDictionary addEntriesFromDictionary:@{
@".aar" : extractAppleArchive,
@".yaa" : extractAppleArchive,
}];
}

NSString *lastPathComponent = [path lastPathComponent];
for (NSString *currentType in extractCommandDictionary)
Expand Down Expand Up @@ -93,10 +113,12 @@ - (void)extractArchivePipingDataToCommand:(NSString *)command arguments:(NSArray
@autoreleasepool {
NSString *destination = _extractionDirectory;

NSFileManager *fileManager = [NSFileManager defaultManager];

SULog(SULogLevelDefault, @"Extracting using '%@' '%@' < '%@' '%@'", command, [args componentsJoinedByString:@"' '"], _archivePath, destination);

// Get the file size.
NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:_archivePath error:nil];
NSDictionary *attributes = [fileManager attributesOfItemAtPath:_archivePath error:nil];
NSUInteger expectedLength = [(NSNumber *)[attributes objectForKey:NSFileSize] unsignedIntegerValue];

if (expectedLength == 0) {
Expand Down
8 changes: 4 additions & 4 deletions Configurations/ConfigCommon.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,13 @@ SPARKLE_ICON_NAME = AppIcon
// If you change any of these version details, you must increase CURRENT_PROJECT_VERSION
// These variables must have a space after the '=' too
SPARKLE_VERSION_MAJOR = 2
SPARKLE_VERSION_MINOR = 6
SPARKLE_VERSION_PATCH = 3
SPARKLE_VERSION_MINOR = 7
SPARKLE_VERSION_PATCH = 0

// This should be in SemVer format or empty, ie. "-beta.1"
// These variables must have a space after the '=' too
SPARKLE_VERSION_SUFFIX =
CURRENT_PROJECT_VERSION = 2039
SPARKLE_VERSION_SUFFIX = -beta.1
CURRENT_PROJECT_VERSION = 2040

MARKETING_VERSION = $(SPARKLE_VERSION_MAJOR).$(SPARKLE_VERSION_MINOR).$(SPARKLE_VERSION_PATCH)$(SPARKLE_VERSION_SUFFIX)
ALWAYS_SEARCH_USER_PATHS = NO
Expand Down
8 changes: 8 additions & 0 deletions Sparkle.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,8 @@
726F2CE61BC9C33D001971A4 /* SUOperatingSystem.m in Sources */ = {isa = PBXBuildFile; fileRef = 726F2CE41BC9C33D001971A4 /* SUOperatingSystem.m */; };
726F2CE81BC9C48F001971A4 /* SUConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 61299A5F09CA6EB100B7442F /* SUConstants.m */; };
726F2CEB1BC9C733001971A4 /* SUConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 61299A5F09CA6EB100B7442F /* SUConstants.m */; };
726FC0362C1E787A00177986 /* SparkleTestCodeSignApp.aar in Resources */ = {isa = PBXBuildFile; fileRef = 726FC0352C1E787A00177986 /* SparkleTestCodeSignApp.aar */; };
726FC0382C1E96AA00177986 /* SparkleTestCodeSignApp.enc.aar in Resources */ = {isa = PBXBuildFile; fileRef = 726FC0372C1E96AA00177986 /* SparkleTestCodeSignApp.enc.aar */; };
727DBAE526B5BBFD00111F0C /* ArgumentParser in Frameworks */ = {isa = PBXBuildFile; productRef = 727DBAE426B5BBFD00111F0C /* ArgumentParser */; };
727DBAE726B5C47800111F0C /* ArgumentParser in Frameworks */ = {isa = PBXBuildFile; productRef = 727DBAE626B5C47800111F0C /* ArgumentParser */; };
727DBAE926B5C48A00111F0C /* ArgumentParser in Frameworks */ = {isa = PBXBuildFile; productRef = 727DBAE826B5C48A00111F0C /* ArgumentParser */; };
Expand Down Expand Up @@ -1330,6 +1332,8 @@
726E4A361C89116000C57C6A /* SPUStandardUserDriverDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPUStandardUserDriverDelegate.h; sourceTree = "<group>"; };
726F2CE31BC9C33D001971A4 /* SUOperatingSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SUOperatingSystem.h; sourceTree = "<group>"; };
726F2CE41BC9C33D001971A4 /* SUOperatingSystem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SUOperatingSystem.m; sourceTree = "<group>"; };
726FC0352C1E787A00177986 /* SparkleTestCodeSignApp.aar */ = {isa = PBXFileReference; lastKnownFileType = file; path = SparkleTestCodeSignApp.aar; sourceTree = "<group>"; };
726FC0372C1E96AA00177986 /* SparkleTestCodeSignApp.enc.aar */ = {isa = PBXFileReference; lastKnownFileType = file; path = SparkleTestCodeSignApp.enc.aar; sourceTree = "<group>"; };
726FD2CB25F4BE5F00123BC6 /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = fa.lproj/MainMenu.strings; sourceTree = "<group>"; };
726FD2CC25F4BE5F00123BC6 /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = fa.lproj/Sparkle.strings; sourceTree = "<group>"; };
727F340A2605321D00020E85 /* SULog+NSError.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SULog+NSError.m"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1868,6 +1872,8 @@
729F7ECD27409076004592DC /* SparkleTestCodeSignApp_bad_extraneous.zip */,
72CCDEBD27421FD500B53718 /* SparkleTestCodeSignApp_bad_header.zip */,
F8761EB21ADC50EB000C9034 /* SparkleTestCodeSignApp.zip */,
726FC0352C1E787A00177986 /* SparkleTestCodeSignApp.aar */,
726FC0372C1E96AA00177986 /* SparkleTestCodeSignApp.enc.aar */,
72EB735E29BE981300FBCEE7 /* DevSignedApp.zip */,
72EB736029BEB36100FBCEE7 /* DevSignedAppVersion2.zip */,
14958C6C19AEBC610061B14F /* test-pubkey.pem */,
Expand Down Expand Up @@ -3191,10 +3197,12 @@
5AF6C74F1AEA46D10014A3AB /* test.pkg in Resources */,
72EB735F29BE981300FBCEE7 /* DevSignedApp.zip in Resources */,
72BC6C3D275027BF0083F14B /* SparkleTestCodeSign_apfs.dmg in Resources */,
726FC0382C1E96AA00177986 /* SparkleTestCodeSignApp.enc.aar in Resources */,
720DC50627A62CDC00DFF3EC /* testappcast_minimumAutoupdateVersionSkipping2.xml in Resources */,
5AD0FA7F1C73F2E2004BCEFF /* testappcast.xml in Resources */,
FA30773D24CBC295007BA37D /* testlocalizedreleasenotesappcast.xml in Resources */,
72CCDEBE27421FD500B53718 /* SparkleTestCodeSignApp_bad_header.zip in Resources */,
726FC0362C1E787A00177986 /* SparkleTestCodeSignApp.aar in Resources */,
722545B626805FF80036465C /* testappcast_info_updates.xml in Resources */,
7202DC9A269ABD3500737EC4 /* testappcast_phasedRollout.xml in Resources */,
5F1510A21C96E591006E1629 /* testnamespaces.xml in Resources */,
Expand Down
Binary file added Tests/Resources/SparkleTestCodeSignApp.aar
Binary file not shown.
Binary file added Tests/Resources/SparkleTestCodeSignApp.enc.aar
Binary file not shown.
14 changes: 14 additions & 0 deletions Tests/SUUnarchiverTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,18 @@ class SUUnarchiverTest: XCTestCase
self.unarchiveTestAppWithExtension("pkg", resourceName: "test", expectingInstallationType: SPUInstallationTypeApplication, expectingSuccess: false)
}
#endif

func testUnarchivingAppleArchive() {
self.unarchiveTestAppWithExtension("aar", resourceName: "SparkleTestCodeSignApp")
}

// If we support encrypted archives one day we will use "aea" file extension
// Password to this archive is whatisgoingonforeveroneday!
func testUnarchivingEncryptedAppleArchiveWithoutPassword() {
signal(SIGPIPE, SIG_IGN)

self.unarchiveTestAppWithExtension("enc.aar", resourceName: "SparkleTestCodeSignApp", expectingSuccess: false)

signal(SIGPIPE, SIG_DFL)
}
}
2 changes: 1 addition & 1 deletion generate_appcast/Unarchive.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func unarchiveUpdates(archivesSourceDir: URL, archivesDestDir: URL, disableNeste
let itemURL = archivesSourceDir.appendingPathComponent(item)
let fileExtension = itemURL.pathExtension
// Note: keep this list in sync with SUPipedUnarchiver
guard ["zip", "tar", "gz", "tgz", "bz2", "tbz", "xz", "txz", "lzma", "dmg"].contains(fileExtension) else {
guard ["zip", "tar", "gz", "tgz", "bz2", "tbz", "xz", "txz", "lzma", "dmg", "aar", "yaa"].contains(fileExtension) else {
continue
}

Expand Down
Loading