5 Commits

Author SHA1 Message Date
macmade 87f051a3a1 1.1.2-39 2021-10-08 17:05:15 +02:00
macmade 6ffa0a951d Preparing for 1.1.2 2021-10-08 17:02:48 +02:00
macmade 8a0489103a Reading history from all pages 2021-10-08 17:02:01 +02:00
macmade 18debc3ed3 Better error reporting. Fixed altool location for latest Xcode versions. 2021-10-08 16:42:09 +02:00
macmade 7b6f1db509 Travis 2020-11-20 06:36:25 +01:00
5 changed files with 138 additions and 64 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
language: objective-c
xcode_project: Notarize.xcodeproj
xcode_scheme: Notarize
osx_image: xcode10
osx_image: xcode12
script:
- xcodebuild build -project Notarize.xcodeproj -scheme Notarize
+2 -2
View File
@@ -563,7 +563,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.1.1;
MARKETING_VERSION = 1.1.2;
PRODUCT_BUNDLE_IDENTIFIER = "com.xs-labs.Notarize";
PRODUCT_NAME = "$(TARGET_NAME)";
};
@@ -577,7 +577,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.1.1;
MARKETING_VERSION = 1.1.2;
PRODUCT_BUNDLE_IDENTIFIER = "com.xs-labs.Notarize";
PRODUCT_NAME = "$(TARGET_NAME)";
};
+67 -41
View File
@@ -31,9 +31,12 @@ class ALTool
class func isAvailable() -> Bool
{
let out = try? ALTool.run( arguments: [ "--help" ] )
guard let out = try? ALTool.run( arguments: [ "--help" ] ) else
{
return false
}
return out?.count ?? 0 > 0
return out.stdout.count > 0 || out.stderr.count > 0
}
init( username: String, password: String )
@@ -44,56 +47,69 @@ class ALTool
func checkPassword() throws
{
do
{
let _ = try ALTool.run( arguments: [ "--notarization-history", "-u", self.username, "-p", self.password, "--output-format", "xml" ] )
}
catch let e as NSError
{
throw e
}
let _ = try ALTool.run( arguments: [ "--notarization-history", "0", "-u", self.username, "-p", self.password, "--output-format", "xml" ] )
}
func notarizationHistory() throws -> String?
func notarizationHistory( page: Int64 ) throws -> String?
{
do
{
let out = try ALTool.run( arguments: [ "--notarization-history", "-u", self.username, "-p", self.password, "--output-format", "xml" ] )
return out.trimmingCharacters( in: NSCharacterSet.whitespacesAndNewlines )
}
catch let e as NSError
{
throw e
}
let out = try ALTool.run( arguments: [ "--notarization-history", "\( page )", "-u", self.username, "-p", self.password, "--output-format", "xml" ] )
return out.stdout.trimmingCharacters( in: NSCharacterSet.whitespacesAndNewlines )
}
func notarizationInfo( for uuid: String ) throws -> String?
{
do
{
let out = try ALTool.run( arguments: [ "--notarization-info", uuid, "-u", self.username, "-p", self.password, "--output-format", "xml" ] )
return out.trimmingCharacters( in: NSCharacterSet.whitespacesAndNewlines )
}
catch let e as NSError
{
throw e
}
let out = try ALTool.run( arguments: [ "--notarization-info", uuid, "-u", self.username, "-p", self.password, "--output-format", "xml" ] )
return out.stdout.trimmingCharacters( in: NSCharacterSet.whitespacesAndNewlines )
}
private class func run( arguments: [ String ] ) throws -> String
private class var executablePath: String?
{
var args = [ "altool" ]
args.append( contentsOf: arguments )
let pipe = Pipe()
let process = Process()
process.launchPath = "/usr/bin/xcrun"
process.arguments = args
process.arguments = [ "-f", "altool" ]
process.standardOutput = pipe
do
{
try process.run()
}
catch let e as NSError
{
Swift.print( e )
return nil
}
process.waitUntilExit()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
guard let out = String( bytes: data, encoding: .utf8 ) else
{
return nil
}
return out.trimmingCharacters( in: .whitespacesAndNewlines )
}
private class func run( arguments: [ String ] ) throws -> ( stdout: String, stderr: String )
{
guard let exec = ALTool.executablePath else
{
throw NSError( domain: NSCocoaErrorDomain, code: -1, userInfo: [ NSLocalizedDescriptionKey : "altool executable not found" ] )
}
let pipeOut = Pipe()
let pipeErr = Pipe()
let process = Process()
process.launchPath = exec
process.arguments = arguments
process.standardOutput = pipeOut
process.standardError = pipeErr
do
{
try process.run()
@@ -107,9 +123,12 @@ class ALTool
process.waitUntilExit()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let dataOut = pipeOut.fileHandleForReading.readDataToEndOfFile()
let dataErr = pipeErr.fileHandleForReading.readDataToEndOfFile()
guard let out = String( bytes: data, encoding: .utf8 ) else
guard let out = String( bytes: dataOut, encoding: .utf8 ),
let err = String( bytes: dataErr, encoding: .utf8 )
else
{
throw NSError( domain: NSCocoaErrorDomain, code: -1, userInfo: [ NSLocalizedDescriptionKey : "No data received from altool" ] )
}
@@ -127,13 +146,20 @@ class ALTool
let code = errorDict.object( forKey: "code" ) as? NSNumber ?? NSNumber( integerLiteral: 0 )
let message = errorDict.object( forKey: "message" ) as? NSString ?? "Unknown error" as NSString
throw NSError( domain: NSCocoaErrorDomain, code: code.intValue, userInfo: [ NSLocalizedDescriptionKey : "Error", NSLocalizedRecoverySuggestionErrorKey : message ] )
if let info = errorDict.object( forKey: "userInfo" ) as? NSDictionary, let failure = info.object( forKey: "NSLocalizedFailureReason" ) as? NSString
{
throw NSError( domain: NSCocoaErrorDomain, code: code.intValue, userInfo: [ NSLocalizedDescriptionKey : message, NSLocalizedRecoverySuggestionErrorKey : failure ] )
}
else
{
throw NSError( domain: NSCocoaErrorDomain, code: code.intValue, userInfo: [ NSLocalizedDescriptionKey : "Error", NSLocalizedRecoverySuggestionErrorKey : message ] )
}
}
}
}
}
}
return out
return ( stdout: out, stderr: err )
}
}
+67 -19
View File
@@ -134,39 +134,87 @@ class HistoryViewController: NSViewController, NSTableViewDelegate, NSTableViewD
DispatchQueue.global( qos: .userInitiated ).async
{
let altool = ALTool( username: account.username, password: password )
let xml = try? altool.notarizationHistory()
if let xmlData = xml?.data( using: .utf8 )
do
{
if let history = try? PropertyListSerialization.propertyList( from: xmlData, options: [], format: nil ) as? NSDictionary
let items = try self.loadHistory( username: account.username, password: password )
DispatchQueue.main.async
{
let items = HistoryItem.ItemsFromDictionary( dict: history )
DispatchQueue.main.async
items.forEach
{
items.forEach
o in
if self.items.contains( o ) == false
{
o in
if self.items.contains( o ) == false
{
self.items.insert( o )
}
self.items.insert( o )
}
}
self.loading = false
self.refreshing = false
}
}
DispatchQueue.main.async
catch let error
{
self.loading = false
self.refreshing = false
if userInitiated
{
DispatchQueue.main.async
{
let alert = NSAlert( error: error )
if let window = self.view.window
{
alert.beginSheetModal( for: window, completionHandler: nil )
}
else
{
alert.runModal()
}
self.loading = false
self.refreshing = false
}
}
else
{
print( error )
}
}
}
}
}
private func loadHistory( username: String, password: String ) throws -> [ HistoryItem ]
{
var items = [ HistoryItem ]()
let altool = ALTool( username: username, password: password )
var page = Int64( 0 )
repeat
{
let xml = try altool.notarizationHistory( page: page )
page = -1
if let xmlData = xml?.data( using: .utf8 )
{
if let history = try? PropertyListSerialization.propertyList( from: xmlData, options: [], format: nil ) as? NSDictionary
{
let current = HistoryItem.ItemsFromDictionary( dict: history )
items.append( contentsOf: current )
if current.count > 0, let history = history.object( forKey: "notarization-history" ) as? NSDictionary, let next = history.object( forKey: "next-page" ) as? Int64
{
page = next
}
}
}
}
while page >= 0
return items
}
private func getInfo()
{
DispatchQueue.main.async
+1 -1
View File
@@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>34</string>
<string>39</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string>
<key>LSMinimumSystemVersion</key>