Compare commits
84
Commits
renames-rebase
...
0.1.9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37cd028730 | ||
|
|
cc8993e6e7 | ||
|
|
a0b35f490b | ||
|
|
ed0614d8cf | ||
|
|
ea70eb937a | ||
|
|
b5ecff7e03 | ||
|
|
8589cbedbb | ||
|
|
edc604bfec | ||
|
|
8995e0faeb | ||
|
|
67a68bef8c | ||
|
|
7c4b43d2d1 | ||
|
|
694f96abec | ||
|
|
369854b103 | ||
|
|
104ebb9442 | ||
|
|
e1f56bfdc6 | ||
|
|
4a50411246 | ||
|
|
fc3ce8158c | ||
|
|
6e1e11809e | ||
|
|
9d67b82d5c | ||
|
|
09a3b74f93 | ||
|
|
c108f4aac4 | ||
|
|
0ac595efd9 | ||
|
|
ce1b59c1cf | ||
|
|
f7438e91b3 | ||
|
|
656d2cdd29 | ||
|
|
d8a244dd1a | ||
|
|
2dea99045d | ||
|
|
483eb38d73 | ||
|
|
475c50a8e3 | ||
|
|
4384ccb485 | ||
|
|
4b4bb7c87c | ||
|
|
cd6ccb9c7b | ||
|
|
0c91d7fe9c | ||
|
|
0d8fe0f642 | ||
|
|
b6f4e70731 | ||
|
|
efd944e337 | ||
|
|
cc86db04e2 | ||
|
|
c9ce161632 | ||
|
|
f924fc3023 | ||
|
|
5bfd32eeae | ||
|
|
7c365d304f | ||
|
|
a6a782aefb | ||
|
|
aa72c42c3b | ||
|
|
bee2be5dfb | ||
|
|
9bcc86be72 | ||
|
|
d0c932a90d | ||
|
|
4a0aa59d25 | ||
|
|
70a838c834 | ||
|
|
19dc11c735 | ||
|
|
87e854e8d4 | ||
|
|
5640bbe863 | ||
|
|
843ee9fa22 | ||
|
|
95ce084ddd | ||
|
|
ed92f6aad2 | ||
|
|
56f52ccfe4 | ||
|
|
2cc8a7d4ab | ||
|
|
0026cef7bf | ||
|
|
f0fee4a4e8 | ||
|
|
1898bbde62 | ||
|
|
031a7cd850 | ||
|
|
27f7777ba5 | ||
|
|
8caa2fa200 | ||
|
|
2fe45e940f | ||
|
|
e50720470c | ||
|
|
cebf4a85d6 | ||
|
|
5f96d1e565 | ||
|
|
1f3e0ccbe5 | ||
|
|
6252f3dbda | ||
|
|
1e71daa4f7 | ||
|
|
ae89c0a1f6 | ||
|
|
d0634fc8e6 | ||
|
|
178648f373 | ||
|
|
3a4428cfb3 | ||
|
|
dab5bf2892 | ||
|
|
221519e3ad | ||
|
|
7faed9ec18 | ||
|
|
c74ecf9c07 | ||
|
|
04233f8f7c | ||
|
|
378e3891bf | ||
|
|
9e040347f5 | ||
|
|
c99ce7dfbb | ||
|
|
6b017d5d3f | ||
|
|
b1f4ecf615 | ||
|
|
fd29bc392f |
+12
@@ -0,0 +1,12 @@
|
||||
osx_image: xcode7.1
|
||||
language: objective-c
|
||||
before_install:
|
||||
- brew update
|
||||
- brew outdated xctool || brew upgrade xctool
|
||||
install: script/bootstrap
|
||||
script: script/cibuild
|
||||
notifications:
|
||||
email: false
|
||||
env:
|
||||
global:
|
||||
secure: L4C3hHzXc/sgL35dIz3kjqIzPWnXCHsFOgbOcz0f249zlnegeKHQdChm4HUDtfrbmKLMYQCIvVfcgPeLaHkCSeHqXUihXLT2LglK+0GX3MBbFzde9x1uln2O68hH1tTmBg2O2i4Dtc4D3e+2tVv3XmhQDZt0znIVO6n9YgevDqw=
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
github "jspahrsummers/xcconfigs" >= 0.7.1
|
||||
github "Quick/Quick" ~> 0.2
|
||||
github "Quick/Nimble" ~> 0.2
|
||||
github "Quick/Quick" ~> 0.7
|
||||
github "Quick/Nimble" ~> 2.0
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
github "Mantle/Mantle" "1.5.3"
|
||||
github "Quick/Nimble" "v0.2.0"
|
||||
github "Quick/Quick" "v0.2.2"
|
||||
github "ReactiveCocoa/ReactiveCocoa" "v2.4.3"
|
||||
github "jspahrsummers/xcconfigs" "0.7.1"
|
||||
github "Mantle/Mantle" "1.5.6"
|
||||
github "Quick/Nimble" "v2.0.0"
|
||||
github "Quick/Quick" "v0.7.0"
|
||||
github "ReactiveCocoa/ReactiveCocoa" "v2.5"
|
||||
github "jspahrsummers/xcconfigs" "0.8.1"
|
||||
|
||||
Vendored
+1
-1
Submodule Carthage/Checkouts/Mantle updated: f797bd4837...e41221ee94
Vendored
+1
-1
Submodule Carthage/Checkouts/Nimble updated: 6f787eeb75...20a3f3b4e6
Vendored
+1
-1
Submodule Carthage/Checkouts/Quick updated: b0e98286db...7d0b8c2135
Vendored
+1
-1
Submodule Carthage/Checkouts/ReactiveCocoa updated: a6bc3a918d...32364b9040
Vendored
+1
-1
Submodule Carthage/Checkouts/xcconfigs updated: b09b4b6323...99624a6af3
@@ -6,6 +6,7 @@ and transparent as updates to a website**.
|
||||
Instead of publishing a feed of versions from which your app must select,
|
||||
Squirrel updates to the version your server tells it to. This allows you to
|
||||
intelligently update your clients based on the request you give to Squirrel.
|
||||
The server can remotely drive behaviors like rolling back or phased rollouts.
|
||||
|
||||
Your request can include authentication details, custom headers or a request
|
||||
body so that your server has the context it needs in order to supply the most
|
||||
@@ -158,7 +159,7 @@ to the update request provided:
|
||||
"url": "http://mycompany.com/myapp/releases/myrelease",
|
||||
"name": "My Release Name",
|
||||
"notes": "Theses are some release notes innit",
|
||||
"pub_date": "2013-09-18T12:29:53+01:00",
|
||||
"pub_date": "2013-09-18T12:29:53+01:00"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
534FF36717D8E90A0020A51A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 534FF36517D8E90A0020A51A /* InfoPlist.strings */; };
|
||||
534FF36A17D8E90A0020A51A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 534FF36917D8E90A0020A51A /* main.m */; };
|
||||
534FF37317D8E9370020A51A /* com.github.Squirrel.TestApplication.TestService.xpc in Copy XPCServices */ = {isa = PBXBuildFile; fileRef = 534FF36017D8E90A0020A51A /* com.github.Squirrel.TestApplication.TestService.xpc */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
53710D7417D8F59700A992DE /* SQRLDeepCodesignSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 53710D7317D8F59700A992DE /* SQRLDeepCodesignSpec.m */; };
|
||||
53710D8417D8F5CB00A992DE /* deep-codesign in Resources */ = {isa = PBXBuildFile; fileRef = 53710D7F17D8F5C300A992DE /* deep-codesign */; };
|
||||
5371815F18A29DC8005ED798 /* TestAppConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 5371815E18A29DC8005ED798 /* TestAppConstants.m */; };
|
||||
5371816018A29DC8005ED798 /* TestAppConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 5371815E18A29DC8005ED798 /* TestAppConstants.m */; };
|
||||
5374DCC6187AD0D8006B7056 /* SQRLAuthorization.h in Headers */ = {isa = PBXBuildFile; fileRef = 5374DCC4187AD0D8006B7056 /* SQRLAuthorization.h */; };
|
||||
@@ -27,6 +25,8 @@
|
||||
5397A69D187DF8610014A477 /* SQRLInstallerOwnedBundle.m in Sources */ = {isa = PBXBuildFile; fileRef = 5397A5EB187DA2570014A477 /* SQRLInstallerOwnedBundle.m */; };
|
||||
53AACF4B17E9CA0500B41027 /* SQRLUpdate.h in Headers */ = {isa = PBXBuildFile; fileRef = 53AACF4917E9CA0500B41027 /* SQRLUpdate.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
53AACF4C17E9CA0500B41027 /* SQRLUpdate.m in Sources */ = {isa = PBXBuildFile; fileRef = 53AACF4A17E9CA0500B41027 /* SQRLUpdate.m */; };
|
||||
88CA21971BD980FC006693B7 /* MTLEXTRuntimeExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 88CA21941BD980FC006693B7 /* MTLEXTRuntimeExtensions.m */; };
|
||||
88CA21981BD980FC006693B7 /* MTLEXTScope.m in Sources */ = {isa = PBXBuildFile; fileRef = 88CA21961BD980FC006693B7 /* MTLEXTScope.m */; };
|
||||
D000218F17BACEFF0050109A /* SQRLZipArchiver.m in Sources */ = {isa = PBXBuildFile; fileRef = D000218D17BACEFF0050109A /* SQRLZipArchiver.m */; };
|
||||
D000219717BAD34D0050109A /* TestApplication.app.zip in Resources */ = {isa = PBXBuildFile; fileRef = D000219617BAD34D0050109A /* TestApplication.app.zip */; };
|
||||
D000219917BAD35C0050109A /* SQRLZipArchiverSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D000219817BAD35C0050109A /* SQRLZipArchiverSpec.m */; };
|
||||
@@ -55,6 +55,7 @@
|
||||
D06B58B518032B1500656D97 /* RACSignal+SQRLTransactionExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = D06B58B318032B1500656D97 /* RACSignal+SQRLTransactionExtensions.m */; };
|
||||
D06B58B618032B1500656D97 /* RACSignal+SQRLTransactionExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = D06B58B318032B1500656D97 /* RACSignal+SQRLTransactionExtensions.m */; };
|
||||
D06B58D118035B5A00656D97 /* SQRLTerminationListenerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D06B58D018035B5A00656D97 /* SQRLTerminationListenerSpec.m */; };
|
||||
D06F7B101AD72DD30009A3BC /* RACKVOProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = D06F7B0F1AD72DD30009A3BC /* RACKVOProxy.m */; };
|
||||
D08D4E0D17B451500012B22D /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0C22BDA179CC00E00158214 /* Cocoa.framework */; };
|
||||
D08D4E1317B451500012B22D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D08D4E1117B451500012B22D /* InfoPlist.strings */; };
|
||||
D08D4E1517B451500012B22D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D08D4E1417B451500012B22D /* main.m */; };
|
||||
@@ -74,7 +75,6 @@
|
||||
D09C66291A00520B007D7ED0 /* NSArray+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D09C66281A00520B007D7ED0 /* NSArray+RACSequenceAdditions.m */; };
|
||||
D09C662C1A005226007D7ED0 /* NSObject+RACKVOWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = D09C662A1A005226007D7ED0 /* NSObject+RACKVOWrapper.m */; };
|
||||
D09C662D1A005226007D7ED0 /* NSObject+RACPropertySubscribing.m in Sources */ = {isa = PBXBuildFile; fileRef = D09C662B1A005226007D7ED0 /* NSObject+RACPropertySubscribing.m */; };
|
||||
D09C66331A0052DE007D7ED0 /* EXTRuntimeExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = D09C66321A0052DE007D7ED0 /* EXTRuntimeExtensions.m */; };
|
||||
D09C66351A00535B007D7ED0 /* RACKVOTrampoline.m in Sources */ = {isa = PBXBuildFile; fileRef = D09C66341A00535B007D7ED0 /* RACKVOTrampoline.m */; };
|
||||
D09C66381A00537A007D7ED0 /* NSObject+RACDeallocating.m in Sources */ = {isa = PBXBuildFile; fileRef = D09C66361A00537A007D7ED0 /* NSObject+RACDeallocating.m */; };
|
||||
D09C66391A00537A007D7ED0 /* NSObject+RACDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = D09C66371A00537A007D7ED0 /* NSObject+RACDescription.m */; };
|
||||
@@ -145,7 +145,6 @@
|
||||
D0C22C52179CC23900158214 /* Squirrel.h in Headers */ = {isa = PBXBuildFile; fileRef = D0C22BE7179CC00E00158214 /* Squirrel.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D0D2B6261804E903000EA901 /* SQRLDirectoryManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D0D2B6241804E903000EA901 /* SQRLDirectoryManager.m */; };
|
||||
D0D2B6271804E903000EA901 /* SQRLDirectoryManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D0D2B6241804E903000EA901 /* SQRLDirectoryManager.m */; };
|
||||
D0D97E4517B58FC400301C72 /* ResourceRules.plist in Resources */ = {isa = PBXBuildFile; fileRef = D0D97E4417B58FC400301C72 /* ResourceRules.plist */; };
|
||||
D0EDBE9D17B0C68E0058BC3C /* NSError+SQRLVerbosityExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = D0EDBE9B17B0C68E0058BC3C /* NSError+SQRLVerbosityExtensions.m */; };
|
||||
D0EDBEDD17B0DB3E0058BC3C /* QuickSpec+SQRLFixtures.m in Sources */ = {isa = PBXBuildFile; fileRef = D0EDBEDC17B0DB3E0058BC3C /* QuickSpec+SQRLFixtures.m */; };
|
||||
D0EDBEE117B0E3650058BC3C /* SQRLCodeSignatureSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D0EDBEE017B0E3650058BC3C /* SQRLCodeSignatureSpec.m */; };
|
||||
@@ -267,10 +266,8 @@
|
||||
534FF36617D8E90A0020A51A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
534FF36817D8E90A0020A51A /* TestService-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TestService-Prefix.pch"; sourceTree = "<group>"; };
|
||||
534FF36917D8E90A0020A51A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
53710D7317D8F59700A992DE /* SQRLDeepCodesignSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQRLDeepCodesignSpec.m; sourceTree = "<group>"; };
|
||||
53710D7D17D8F5C300A992DE /* bootstrap */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = bootstrap; sourceTree = "<group>"; };
|
||||
53710D7E17D8F5C300A992DE /* cibuild */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = cibuild; sourceTree = "<group>"; };
|
||||
53710D7F17D8F5C300A992DE /* deep-codesign */ = {isa = PBXFileReference; lastKnownFileType = text; path = "deep-codesign"; sourceTree = "<group>"; };
|
||||
53710D8017D8F5C300A992DE /* LICENSE.md */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE.md; sourceTree = "<group>"; };
|
||||
53710D8117D8F5C300A992DE /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.md; sourceTree = "<group>"; };
|
||||
53710D8217D8F5C300A992DE /* targets.awk */ = {isa = PBXFileReference; lastKnownFileType = text; path = targets.awk; sourceTree = "<group>"; };
|
||||
@@ -287,6 +284,12 @@
|
||||
5397A69C187DF6490014A477 /* SQRLInstaller+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SQRLInstaller+Private.h"; sourceTree = "<group>"; };
|
||||
53AACF4917E9CA0500B41027 /* SQRLUpdate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQRLUpdate.h; sourceTree = "<group>"; };
|
||||
53AACF4A17E9CA0500B41027 /* SQRLUpdate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQRLUpdate.m; sourceTree = "<group>"; };
|
||||
88CA21911BD980FC006693B7 /* metamacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = metamacros.h; path = Carthage/Checkouts/Mantle/Mantle/extobjc/metamacros.h; sourceTree = SOURCE_ROOT; };
|
||||
88CA21921BD980FC006693B7 /* MTLEXTKeyPathCoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MTLEXTKeyPathCoding.h; path = Carthage/Checkouts/Mantle/Mantle/extobjc/MTLEXTKeyPathCoding.h; sourceTree = SOURCE_ROOT; };
|
||||
88CA21931BD980FC006693B7 /* MTLEXTRuntimeExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MTLEXTRuntimeExtensions.h; path = Carthage/Checkouts/Mantle/Mantle/extobjc/MTLEXTRuntimeExtensions.h; sourceTree = SOURCE_ROOT; };
|
||||
88CA21941BD980FC006693B7 /* MTLEXTRuntimeExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MTLEXTRuntimeExtensions.m; path = Carthage/Checkouts/Mantle/Mantle/extobjc/MTLEXTRuntimeExtensions.m; sourceTree = SOURCE_ROOT; };
|
||||
88CA21951BD980FC006693B7 /* MTLEXTScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MTLEXTScope.h; path = Carthage/Checkouts/Mantle/Mantle/extobjc/MTLEXTScope.h; sourceTree = SOURCE_ROOT; };
|
||||
88CA21961BD980FC006693B7 /* MTLEXTScope.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MTLEXTScope.m; path = Carthage/Checkouts/Mantle/Mantle/extobjc/MTLEXTScope.m; sourceTree = SOURCE_ROOT; };
|
||||
D000218C17BACEFF0050109A /* SQRLZipArchiver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQRLZipArchiver.h; sourceTree = "<group>"; };
|
||||
D000218D17BACEFF0050109A /* SQRLZipArchiver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQRLZipArchiver.m; sourceTree = "<group>"; };
|
||||
D000219617BAD34D0050109A /* TestApplication.app.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = TestApplication.app.zip; sourceTree = "<group>"; };
|
||||
@@ -314,6 +317,7 @@
|
||||
D06B58B218032B1500656D97 /* RACSignal+SQRLTransactionExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RACSignal+SQRLTransactionExtensions.h"; sourceTree = "<group>"; };
|
||||
D06B58B318032B1500656D97 /* RACSignal+SQRLTransactionExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RACSignal+SQRLTransactionExtensions.m"; sourceTree = "<group>"; };
|
||||
D06B58D018035B5A00656D97 /* SQRLTerminationListenerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQRLTerminationListenerSpec.m; sourceTree = "<group>"; };
|
||||
D06F7B0F1AD72DD30009A3BC /* RACKVOProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACKVOProxy.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACKVOProxy.m; sourceTree = SOURCE_ROOT; };
|
||||
D08D4E0C17B451500012B22D /* TestApplication.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestApplication.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D08D4E1017B451500012B22D /* TestApplication-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "TestApplication-Info.plist"; sourceTree = "<group>"; };
|
||||
D08D4E1217B451500012B22D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
@@ -331,8 +335,6 @@
|
||||
D09C66281A00520B007D7ED0 /* NSArray+RACSequenceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSArray+RACSequenceAdditions.m"; path = "Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/NSArray+RACSequenceAdditions.m"; sourceTree = SOURCE_ROOT; };
|
||||
D09C662A1A005226007D7ED0 /* NSObject+RACKVOWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSObject+RACKVOWrapper.m"; path = "Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/NSObject+RACKVOWrapper.m"; sourceTree = SOURCE_ROOT; };
|
||||
D09C662B1A005226007D7ED0 /* NSObject+RACPropertySubscribing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSObject+RACPropertySubscribing.m"; path = "Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/NSObject+RACPropertySubscribing.m"; sourceTree = SOURCE_ROOT; };
|
||||
D09C66311A0052DE007D7ED0 /* EXTRuntimeExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EXTRuntimeExtensions.h; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/extobjc/EXTRuntimeExtensions.h; sourceTree = SOURCE_ROOT; };
|
||||
D09C66321A0052DE007D7ED0 /* EXTRuntimeExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EXTRuntimeExtensions.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/extobjc/EXTRuntimeExtensions.m; sourceTree = SOURCE_ROOT; };
|
||||
D09C66341A00535B007D7ED0 /* RACKVOTrampoline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACKVOTrampoline.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACKVOTrampoline.m; sourceTree = SOURCE_ROOT; };
|
||||
D09C66361A00537A007D7ED0 /* NSObject+RACDeallocating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSObject+RACDeallocating.m"; path = "Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/NSObject+RACDeallocating.m"; sourceTree = SOURCE_ROOT; };
|
||||
D09C66371A00537A007D7ED0 /* NSObject+RACDescription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSObject+RACDescription.m"; path = "Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/NSObject+RACDescription.m"; sourceTree = SOURCE_ROOT; };
|
||||
@@ -422,7 +424,6 @@
|
||||
D0C22C4F179CC18C00158214 /* SQRLUpdaterSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQRLUpdaterSpec.m; sourceTree = "<group>"; };
|
||||
D0D2B6231804E903000EA901 /* SQRLDirectoryManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQRLDirectoryManager.h; sourceTree = "<group>"; };
|
||||
D0D2B6241804E903000EA901 /* SQRLDirectoryManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQRLDirectoryManager.m; sourceTree = "<group>"; };
|
||||
D0D97E4417B58FC400301C72 /* ResourceRules.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = ResourceRules.plist; sourceTree = "<group>"; };
|
||||
D0EDBE9A17B0C68E0058BC3C /* NSError+SQRLVerbosityExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSError+SQRLVerbosityExtensions.h"; path = "Squirrel/NSError+SQRLVerbosityExtensions.h"; sourceTree = SOURCE_ROOT; };
|
||||
D0EDBE9B17B0C68E0058BC3C /* NSError+SQRLVerbosityExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSError+SQRLVerbosityExtensions.m"; path = "Squirrel/NSError+SQRLVerbosityExtensions.m"; sourceTree = SOURCE_ROOT; };
|
||||
D0EDBEDB17B0DB3E0058BC3C /* QuickSpec+SQRLFixtures.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "QuickSpec+SQRLFixtures.h"; sourceTree = "<group>"; };
|
||||
@@ -529,7 +530,6 @@
|
||||
children = (
|
||||
53710D7D17D8F5C300A992DE /* bootstrap */,
|
||||
53710D7E17D8F5C300A992DE /* cibuild */,
|
||||
53710D7F17D8F5C300A992DE /* deep-codesign */,
|
||||
53710D8017D8F5C300A992DE /* LICENSE.md */,
|
||||
53710D8117D8F5C300A992DE /* README.md */,
|
||||
53710D8217D8F5C300A992DE /* targets.awk */,
|
||||
@@ -621,7 +621,6 @@
|
||||
D08D4E0F17B451500012B22D /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D0D97E4417B58FC400301C72 /* ResourceRules.plist */,
|
||||
D0B1DDCB17B487D90059C355 /* unused-helper */,
|
||||
D08D4E1017B451500012B22D /* TestApplication-Info.plist */,
|
||||
D08D4E1117B451500012B22D /* InfoPlist.strings */,
|
||||
@@ -687,8 +686,12 @@
|
||||
D0AFE3371A00282000C6048F /* Static Dependencies */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D09C66311A0052DE007D7ED0 /* EXTRuntimeExtensions.h */,
|
||||
D09C66321A0052DE007D7ED0 /* EXTRuntimeExtensions.m */,
|
||||
88CA21911BD980FC006693B7 /* metamacros.h */,
|
||||
88CA21921BD980FC006693B7 /* MTLEXTKeyPathCoding.h */,
|
||||
88CA21931BD980FC006693B7 /* MTLEXTRuntimeExtensions.h */,
|
||||
88CA21941BD980FC006693B7 /* MTLEXTRuntimeExtensions.m */,
|
||||
88CA21951BD980FC006693B7 /* MTLEXTScope.h */,
|
||||
88CA21961BD980FC006693B7 /* MTLEXTScope.m */,
|
||||
D0AFE3381A00282C00C6048F /* MTLJSONAdapter.m */,
|
||||
D0AFE3391A00282C00C6048F /* MTLModel.m */,
|
||||
D09C66401A005592007D7ED0 /* MTLModel+NSCoding.m */,
|
||||
@@ -722,6 +725,7 @@
|
||||
D0AFE3551A0028A400C6048F /* RACEvent.m */,
|
||||
D0AFE3561A0028A400C6048F /* RACGroupedSignal.m */,
|
||||
D0AFE3571A0028A400C6048F /* RACImmediateScheduler.m */,
|
||||
D06F7B0F1AD72DD30009A3BC /* RACKVOProxy.m */,
|
||||
D09C66341A00535B007D7ED0 /* RACKVOTrampoline.m */,
|
||||
D0AFE3581A0028A400C6048F /* RACMulticastConnection.m */,
|
||||
D09C663A1A00538D007D7ED0 /* RACObjCRuntime.m */,
|
||||
@@ -922,7 +926,6 @@
|
||||
children = (
|
||||
D00F5B8D17E82DE6009A4818 /* NSProcessInfoExtensionsSpec.m */,
|
||||
D0EDBEE017B0E3650058BC3C /* SQRLCodeSignatureSpec.m */,
|
||||
53710D7317D8F59700A992DE /* SQRLDeepCodesignSpec.m */,
|
||||
D049059A180554BA004E683E /* SQRLDirectoryManagerSpec.m */,
|
||||
D09D244017B595470001FAF8 /* SQRLInstallerSpec.m */,
|
||||
D049059C18055671004E683E /* SQRLShipItRequestSpec.m */,
|
||||
@@ -1070,7 +1073,8 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
CLASSPREFIX = SQRL;
|
||||
LastUpgradeCheck = 0620;
|
||||
LastSwiftUpdateCheck = 0710;
|
||||
LastUpgradeCheck = 0710;
|
||||
ORGANIZATIONNAME = GitHub;
|
||||
};
|
||||
buildConfigurationList = D0C22BD1179CC00E00158214 /* Build configuration list for PBXProject "Squirrel" */;
|
||||
@@ -1111,7 +1115,6 @@
|
||||
D08D4E1317B451500012B22D /* InfoPlist.strings in Resources */,
|
||||
D08D4E2117B451500012B22D /* Images.xcassets in Resources */,
|
||||
D08D4E1917B451500012B22D /* Credits.rtf in Resources */,
|
||||
D0D97E4517B58FC400301C72 /* ResourceRules.plist in Resources */,
|
||||
D03BE98D17B6174500458593 /* MainMenu.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -1130,7 +1133,6 @@
|
||||
D08D4E4A17B451FD0012B22D /* TestApplication.app in Resources */,
|
||||
D09D244A17B59AB30001FAF8 /* TestApplication 2.1.app in Resources */,
|
||||
D000219717BAD34D0050109A /* TestApplication.app.zip in Resources */,
|
||||
53710D8417D8F5CB00A992DE /* deep-codesign in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -1164,6 +1166,7 @@
|
||||
D0AFE37C1A0028B000C6048F /* RACCompoundDisposableProvider.d in Sources */,
|
||||
D0AFE3441A00285000C6048F /* NSValueTransformer+MTLPredefinedTransformerAdditions.m in Sources */,
|
||||
D0AFE38B1A0028EC00C6048F /* RACArraySequence.m in Sources */,
|
||||
D06F7B101AD72DD30009A3BC /* RACKVOProxy.m in Sources */,
|
||||
D0AFE3751A0028A400C6048F /* RACSubject.m in Sources */,
|
||||
D014AC0517B97885007D79D0 /* ShipIt-main.m in Sources */,
|
||||
D0AFE3431A00285000C6048F /* MTLReflection.m in Sources */,
|
||||
@@ -1194,11 +1197,11 @@
|
||||
D0AFE38E1A0028EC00C6048F /* RACUnarySequence.m in Sources */,
|
||||
D0AFE33B1A00282C00C6048F /* MTLJSONAdapter.m in Sources */,
|
||||
D09C66351A00535B007D7ED0 /* RACKVOTrampoline.m in Sources */,
|
||||
88CA21981BD980FC006693B7 /* MTLEXTScope.m in Sources */,
|
||||
D0AFE3691A0028A400C6048F /* RACEmptySignal.m in Sources */,
|
||||
D09C66391A00537A007D7ED0 /* NSObject+RACDescription.m in Sources */,
|
||||
D0D2B6271804E903000EA901 /* SQRLDirectoryManager.m in Sources */,
|
||||
D0AFE36D1A0028A400C6048F /* RACImmediateScheduler.m in Sources */,
|
||||
D09C66331A0052DE007D7ED0 /* EXTRuntimeExtensions.m in Sources */,
|
||||
D0AFE36A1A0028A400C6048F /* RACErrorSignal.m in Sources */,
|
||||
D0AFE3791A0028A400C6048F /* RACTuple.m in Sources */,
|
||||
D0AFE3811A0028CC00C6048F /* RACPassthroughSubscriber.m in Sources */,
|
||||
@@ -1207,6 +1210,7 @@
|
||||
D0AFE36C1A0028A400C6048F /* RACGroupedSignal.m in Sources */,
|
||||
D0AFE34B1A00287100C6048F /* RACDisposable.m in Sources */,
|
||||
D0AFE3731A0028A400C6048F /* RACSignalSequence.m in Sources */,
|
||||
88CA21971BD980FC006693B7 /* MTLEXTRuntimeExtensions.m in Sources */,
|
||||
D09C662D1A005226007D7ED0 /* NSObject+RACPropertySubscribing.m in Sources */,
|
||||
D0AFE3861A0028D500C6048F /* RACSignalProvider.d in Sources */,
|
||||
D0AFE36B1A0028A400C6048F /* RACEvent.m in Sources */,
|
||||
@@ -1265,7 +1269,6 @@
|
||||
D06B58D118035B5A00656D97 /* SQRLTerminationListenerSpec.m in Sources */,
|
||||
5371815F18A29DC8005ED798 /* TestAppConstants.m in Sources */,
|
||||
D0EDBEE117B0E3650058BC3C /* SQRLCodeSignatureSpec.m in Sources */,
|
||||
53710D7417D8F59700A992DE /* SQRLDeepCodesignSpec.m in Sources */,
|
||||
D00F5B8E17E82DE6009A4818 /* NSProcessInfoExtensionsSpec.m in Sources */,
|
||||
D049059B180554BA004E683E /* SQRLDirectoryManagerSpec.m in Sources */,
|
||||
5397A69D187DF8610014A477 /* SQRLInstallerOwnedBundle.m in Sources */,
|
||||
@@ -1340,6 +1343,7 @@
|
||||
GCC_PREFIX_HEADER = "TestService/TestService-Prefix.pch";
|
||||
INFOPLIST_FILE = "TestService/TestService-Info.plist";
|
||||
MACH_O_TYPE = mh_execute;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${PRODUCT_NAME}";
|
||||
PRODUCT_NAME = "com.github.Squirrel.TestApplication.$(TARGET_NAME:rfc1034identifier)";
|
||||
WRAPPER_EXTENSION = xpc;
|
||||
};
|
||||
@@ -1352,6 +1356,7 @@
|
||||
GCC_PREFIX_HEADER = "TestService/TestService-Prefix.pch";
|
||||
INFOPLIST_FILE = "TestService/TestService-Info.plist";
|
||||
MACH_O_TYPE = mh_execute;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${PRODUCT_NAME}";
|
||||
PRODUCT_NAME = "com.github.Squirrel.TestApplication.$(TARGET_NAME:rfc1034identifier)";
|
||||
WRAPPER_EXTENSION = xpc;
|
||||
};
|
||||
@@ -1364,6 +1369,7 @@
|
||||
GCC_PREFIX_HEADER = "TestService/TestService-Prefix.pch";
|
||||
INFOPLIST_FILE = "TestService/TestService-Info.plist";
|
||||
MACH_O_TYPE = mh_execute;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${PRODUCT_NAME}";
|
||||
PRODUCT_NAME = "com.github.Squirrel.TestApplication.$(TARGET_NAME:rfc1034identifier)";
|
||||
WRAPPER_EXTENSION = xpc;
|
||||
};
|
||||
@@ -1376,6 +1382,7 @@
|
||||
GCC_PREFIX_HEADER = "TestService/TestService-Prefix.pch";
|
||||
INFOPLIST_FILE = "TestService/TestService-Info.plist";
|
||||
MACH_O_TYPE = mh_execute;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${PRODUCT_NAME}";
|
||||
PRODUCT_NAME = "com.github.Squirrel.TestApplication.$(TARGET_NAME:rfc1034identifier)";
|
||||
WRAPPER_EXTENSION = xpc;
|
||||
};
|
||||
@@ -1463,10 +1470,10 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "Developer ID Application";
|
||||
CODE_SIGN_RESOURCE_RULES_PATH = TestApplication/ResourceRules.plist;
|
||||
GCC_PREFIX_HEADER = "TestApplication/TestApplication-Prefix.pch";
|
||||
INFOPLIST_FILE = "TestApplication/TestApplication-Info.plist";
|
||||
OTHER_CODE_SIGN_FLAGS = "--timestamp=none";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.Squirrel.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
WRAPPER_EXTENSION = app;
|
||||
@@ -1479,10 +1486,10 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "Developer ID Application";
|
||||
CODE_SIGN_RESOURCE_RULES_PATH = TestApplication/ResourceRules.plist;
|
||||
GCC_PREFIX_HEADER = "TestApplication/TestApplication-Prefix.pch";
|
||||
INFOPLIST_FILE = "TestApplication/TestApplication-Info.plist";
|
||||
OTHER_CODE_SIGN_FLAGS = "--timestamp=none";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.Squirrel.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
WRAPPER_EXTENSION = app;
|
||||
@@ -1495,10 +1502,10 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "Developer ID Application";
|
||||
CODE_SIGN_RESOURCE_RULES_PATH = TestApplication/ResourceRules.plist;
|
||||
GCC_PREFIX_HEADER = "TestApplication/TestApplication-Prefix.pch";
|
||||
INFOPLIST_FILE = "TestApplication/TestApplication-Info.plist";
|
||||
OTHER_CODE_SIGN_FLAGS = "--timestamp=none";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.Squirrel.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
WRAPPER_EXTENSION = app;
|
||||
@@ -1511,10 +1518,10 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "Developer ID Application";
|
||||
CODE_SIGN_RESOURCE_RULES_PATH = TestApplication/ResourceRules.plist;
|
||||
GCC_PREFIX_HEADER = "TestApplication/TestApplication-Prefix.pch";
|
||||
INFOPLIST_FILE = "TestApplication/TestApplication-Info.plist";
|
||||
OTHER_CODE_SIGN_FLAGS = "--timestamp=none";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.Squirrel.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
WRAPPER_EXTENSION = app;
|
||||
@@ -1525,6 +1532,8 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C0B179CC02E00158214 /* Debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
@@ -1535,6 +1544,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C0D179CC02E00158214 /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
@@ -1544,6 +1554,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C1A179CC02E00158214 /* Mac-Framework.xcconfig */;
|
||||
buildSettings = {
|
||||
APPLICATION_EXTENSION_API_ONLY = NO;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
@@ -1552,6 +1563,7 @@
|
||||
Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/extobjc,
|
||||
);
|
||||
INFOPLIST_FILE = "Squirrel/Squirrel-Info.plist";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.${PRODUCT_NAME:rfc1034identifier}";
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
name = Debug;
|
||||
@@ -1560,6 +1572,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C1A179CC02E00158214 /* Mac-Framework.xcconfig */;
|
||||
buildSettings = {
|
||||
APPLICATION_EXTENSION_API_ONLY = NO;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
@@ -1568,6 +1581,7 @@
|
||||
Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/extobjc,
|
||||
);
|
||||
INFOPLIST_FILE = "Squirrel/Squirrel-Info.plist";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.${PRODUCT_NAME:rfc1034identifier}";
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
name = Release;
|
||||
@@ -1586,6 +1600,7 @@
|
||||
);
|
||||
INFOPLIST_FILE = "SquirrelTests/SquirrelTests-Info.plist";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
@@ -1604,6 +1619,7 @@
|
||||
);
|
||||
INFOPLIST_FILE = "SquirrelTests/SquirrelTests-Info.plist";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
@@ -1612,6 +1628,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C0C179CC02E00158214 /* Profile.xcconfig */;
|
||||
buildSettings = {
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
@@ -1621,6 +1638,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C1A179CC02E00158214 /* Mac-Framework.xcconfig */;
|
||||
buildSettings = {
|
||||
APPLICATION_EXTENSION_API_ONLY = NO;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
@@ -1629,6 +1647,7 @@
|
||||
Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/extobjc,
|
||||
);
|
||||
INFOPLIST_FILE = "Squirrel/Squirrel-Info.plist";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.${PRODUCT_NAME:rfc1034identifier}";
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
name = Profile;
|
||||
@@ -1647,6 +1666,7 @@
|
||||
);
|
||||
INFOPLIST_FILE = "SquirrelTests/SquirrelTests-Info.plist";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Profile;
|
||||
@@ -1655,6 +1675,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C0E179CC02E00158214 /* Test.xcconfig */;
|
||||
buildSettings = {
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
@@ -1664,6 +1685,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C1A179CC02E00158214 /* Mac-Framework.xcconfig */;
|
||||
buildSettings = {
|
||||
APPLICATION_EXTENSION_API_ONLY = NO;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
@@ -1672,6 +1694,7 @@
|
||||
Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/extobjc,
|
||||
);
|
||||
INFOPLIST_FILE = "Squirrel/Squirrel-Info.plist";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.${PRODUCT_NAME:rfc1034identifier}";
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
name = Test;
|
||||
@@ -1690,6 +1713,7 @@
|
||||
);
|
||||
INFOPLIST_FILE = "SquirrelTests/SquirrelTests-Info.plist";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Test;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0620"
|
||||
LastUpgradeVersion = "0710"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -37,10 +37,10 @@
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "NO"
|
||||
buildConfiguration = "Debug">
|
||||
shouldUseLaunchSchemeArgsEnv = "NO">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
@@ -69,16 +69,19 @@
|
||||
isEnabled = "YES">
|
||||
</EnvironmentVariable>
|
||||
</EnvironmentVariables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugXPCServices = "NO"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
@@ -100,10 +103,10 @@
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Profile"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Profile"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0620"
|
||||
LastUpgradeVersion = "0710"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -23,10 +23,10 @@
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Test"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Test">
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
@@ -38,15 +38,18 @@
|
||||
ReferencedContainer = "container:Squirrel.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
@@ -62,10 +65,10 @@
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0620"
|
||||
LastUpgradeVersion = "0710"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -23,21 +23,24 @@
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Test"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Test">
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
@@ -52,10 +55,10 @@
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
|
||||
@@ -29,14 +29,24 @@
|
||||
// on-disk locations for. This must not be nil.
|
||||
- (instancetype)initWithApplicationIdentifier:(NSString *)appIdentifier;
|
||||
|
||||
// Finds or creates an Application Support folder.
|
||||
// Finds or creates a storage folder.
|
||||
//
|
||||
// Returns a signal which synchronously sends a URL then completes, or errors.
|
||||
- (RACSignal *)applicationSupportURL;
|
||||
- (RACSignal *)storageURL;
|
||||
|
||||
// Determines where archived `SQRLShipItState` should be saved.
|
||||
//
|
||||
// Returns a signal which synchronously sends a URL then completes, or errors.
|
||||
- (RACSignal *)shipItStateURL;
|
||||
|
||||
// Determines where ShipIt's stdout log should be saved.
|
||||
//
|
||||
// Returns a signal which synchronously sends a URL then completes, or errors.
|
||||
- (RACSignal *)shipItStdoutURL;
|
||||
|
||||
// Determines where ShipIt's stderr log should be saved.
|
||||
//
|
||||
// Returns a signal which synchronously sends a URL then completes, or errors.
|
||||
- (RACSignal *)shipItStderrURL;
|
||||
|
||||
@end
|
||||
|
||||
@@ -47,11 +47,11 @@
|
||||
|
||||
#pragma mark Folder URLs
|
||||
|
||||
- (RACSignal *)applicationSupportURL {
|
||||
- (RACSignal *)storageURL {
|
||||
return [[RACSignal
|
||||
defer:^{
|
||||
NSError *error = nil;
|
||||
NSURL *folderURL = [NSFileManager.defaultManager URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&error];
|
||||
NSURL *folderURL = [NSFileManager.defaultManager URLForDirectory:NSCachesDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&error];
|
||||
if (folderURL == nil) {
|
||||
return [RACSignal error:error];
|
||||
}
|
||||
@@ -63,18 +63,36 @@
|
||||
|
||||
return [RACSignal return:folderURL];
|
||||
}]
|
||||
setNameWithFormat:@"%@ -applicationSupportURL", self];
|
||||
setNameWithFormat:@"%@ -storageURL", self];
|
||||
}
|
||||
|
||||
- (RACSignal *)shipItStateURL {
|
||||
return [[[self
|
||||
applicationSupportURL]
|
||||
storageURL]
|
||||
map:^(NSURL *folderURL) {
|
||||
return [folderURL URLByAppendingPathComponent:@"ShipItState.plist"];
|
||||
}]
|
||||
setNameWithFormat:@"%@ -shipItStateURL", self];
|
||||
}
|
||||
|
||||
- (RACSignal *)shipItStdoutURL {
|
||||
return [[[self
|
||||
storageURL]
|
||||
map:^(NSURL *folderURL) {
|
||||
return [folderURL URLByAppendingPathComponent:@"ShipIt_stdout.log"];
|
||||
}]
|
||||
setNameWithFormat:@"%@ -shipItStdoutURL", self];
|
||||
}
|
||||
|
||||
- (RACSignal *)shipItStderrURL {
|
||||
return [[[self
|
||||
storageURL]
|
||||
map:^(NSURL *folderURL) {
|
||||
return [folderURL URLByAppendingPathComponent:@"ShipIt_stderr.log"];
|
||||
}]
|
||||
setNameWithFormat:@"%@ -shipItStderrURL", self];
|
||||
}
|
||||
|
||||
#pragma mark NSObject
|
||||
|
||||
- (NSString *)description {
|
||||
|
||||
@@ -40,9 +40,9 @@
|
||||
#pragma mark MTLJSONSerializing
|
||||
|
||||
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
|
||||
return [super.JSONKeyPathsByPropertyKey mtl_dictionaryByAddingEntriesFromDictionary:@{
|
||||
return @{
|
||||
@keypath(SQRLDownloadedUpdate.new, bundleURL): NSNull.null
|
||||
}];
|
||||
};
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -31,9 +31,9 @@ const NSInteger SQRLShipItLauncherErrorCouldNotStartService = 1;
|
||||
return [[[RACSignal
|
||||
defer:^{
|
||||
SQRLDirectoryManager *directoryManager = [[SQRLDirectoryManager alloc] initWithApplicationIdentifier:jobLabel];
|
||||
return [directoryManager applicationSupportURL];
|
||||
return [RACSignal zip:@[ [directoryManager shipItStdoutURL], [directoryManager shipItStderrURL] ]];
|
||||
}]
|
||||
map:^(NSURL *appSupportURL) {
|
||||
reduceEach:^(NSURL *stdoutURL, NSURL *stderrURL) {
|
||||
NSBundle *squirrelBundle = [NSBundle bundleForClass:self.class];
|
||||
NSAssert(squirrelBundle != nil, @"Could not open Squirrel.framework bundle");
|
||||
|
||||
@@ -57,8 +57,8 @@ const NSInteger SQRLShipItLauncherErrorCouldNotStartService = 1;
|
||||
[arguments addObject:jobLabel];
|
||||
|
||||
jobDict[@(LAUNCH_JOBKEY_PROGRAMARGUMENTS)] = arguments;
|
||||
jobDict[@(LAUNCH_JOBKEY_STANDARDOUTPATH)] = [appSupportURL URLByAppendingPathComponent:@"ShipIt_stdout.log"].path;
|
||||
jobDict[@(LAUNCH_JOBKEY_STANDARDERRORPATH)] = [appSupportURL URLByAppendingPathComponent:@"ShipIt_stderr.log"].path;
|
||||
jobDict[@(LAUNCH_JOBKEY_STANDARDOUTPATH)] = stdoutURL.path;
|
||||
jobDict[@(LAUNCH_JOBKEY_STANDARDERRORPATH)] = stderrURL.path;
|
||||
|
||||
return jobDict;
|
||||
}]
|
||||
|
||||
@@ -74,7 +74,7 @@ NSString * const SQRLUpdateJSONPublicationDateKey = @"pub_date";
|
||||
|
||||
+ (NSValueTransformer *)releaseDateJSONTransformer {
|
||||
// ISO 8601 Time Zone with ':'
|
||||
NSString * const ISO8601DateFormat = @"yyyy'-'MM'-'DD'T'HH':'mm':'ssZZZZZ";
|
||||
NSString * const ISO8601DateFormat = @"yyyy'-'MM'-'dd'T'HH':'mm':'ssZZZZZ";
|
||||
|
||||
return [MTLValueTransformer reversibleTransformerWithForwardBlock:^ NSDate * (NSString *dateString) {
|
||||
if (![dateString isKindOfClass:NSString.class]) return nil;
|
||||
|
||||
+97
-46
@@ -40,6 +40,10 @@ static NSString * const SQRLUpdaterUniqueTemporaryDirectoryPrefix = @"update.";
|
||||
|
||||
@property (atomic, readwrite) SQRLUpdaterState state;
|
||||
|
||||
/// The etag of the currently downloaded update, nil if no update has been
|
||||
/// downloaded.
|
||||
@property (atomic, copy) NSString *etag;
|
||||
|
||||
// The code signature for the running application, used to check updates before
|
||||
// sending them to ShipIt.
|
||||
@property (nonatomic, strong, readonly) SQRLCodeSignature *signature;
|
||||
@@ -49,16 +53,6 @@ static NSString * const SQRLUpdaterUniqueTemporaryDirectoryPrefix = @"update.";
|
||||
// Sends completed or error.
|
||||
@property (nonatomic, strong, readonly) RACSignal *shipItLauncher;
|
||||
|
||||
// Lazily removes outdated temporary directories (used for previous updates)
|
||||
// upon first subscription.
|
||||
//
|
||||
// Pruning directories while an update is pending or in progress will result in
|
||||
// undefined behavior.
|
||||
//
|
||||
// Sends each removed directory then completes, or errors, on an unspecified
|
||||
// thread.
|
||||
@property (nonatomic, strong, readonly) RACSignal *prunedUpdateDirectories;
|
||||
|
||||
// Parses an update model from downloaded data.
|
||||
//
|
||||
// data - JSON data representing an update manifest. This must not be nil.
|
||||
@@ -169,33 +163,6 @@ static NSString * const SQRLUpdaterUniqueTemporaryDirectoryPrefix = @"update.";
|
||||
BOOL updatesDisabled = (getenv("DISABLE_UPDATE_CHECK") != NULL);
|
||||
@weakify(self);
|
||||
|
||||
_prunedUpdateDirectories = [[[[RACSignal
|
||||
defer:^{
|
||||
SQRLDirectoryManager *directoryManager = [[SQRLDirectoryManager alloc] initWithApplicationIdentifier:SQRLShipItLauncher.shipItJobLabel];
|
||||
return [directoryManager applicationSupportURL];
|
||||
}]
|
||||
flattenMap:^(NSURL *appSupportURL) {
|
||||
NSFileManager *manager = [[NSFileManager alloc] init];
|
||||
NSDirectoryEnumerator *enumerator = [manager enumeratorAtURL:appSupportURL includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsSubdirectoryDescendants errorHandler:^(NSURL *URL, NSError *error) {
|
||||
NSLog(@"Error enumerating item %@ within directory %@: %@", URL, appSupportURL, error);
|
||||
return YES;
|
||||
}];
|
||||
|
||||
return [[enumerator.rac_sequence.signal
|
||||
filter:^(NSURL *enumeratedURL) {
|
||||
NSString *name = enumeratedURL.lastPathComponent;
|
||||
return [name hasPrefix:SQRLUpdaterUniqueTemporaryDirectoryPrefix];
|
||||
}]
|
||||
doNext:^(NSURL *directoryURL) {
|
||||
NSError *error = nil;
|
||||
if (![manager removeItemAtURL:directoryURL error:&error]) {
|
||||
NSLog(@"Error removing old update directory at %@: %@", directoryURL, error.sqrl_verboseDescription);
|
||||
}
|
||||
}];
|
||||
}]
|
||||
replayLazily]
|
||||
setNameWithFormat:@"%@ -prunedUpdateDirectories", self];
|
||||
|
||||
_checkForUpdatesCommand = [[RACCommand alloc] initWithEnabled:[RACSignal return:@(!updatesDisabled)] signalBlock:^(id _) {
|
||||
@strongify(self);
|
||||
NSParameterAssert(self.updateRequest != nil);
|
||||
@@ -204,12 +171,8 @@ static NSString * const SQRLUpdaterUniqueTemporaryDirectoryPrefix = @"update.";
|
||||
NSMutableURLRequest *request = [self.updateRequest mutableCopy];
|
||||
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
|
||||
|
||||
// Prune old updates before the first update check.
|
||||
return [[[[[[[[self.prunedUpdateDirectories
|
||||
catch:^(NSError *error) {
|
||||
NSLog(@"Error pruning old updates: %@", error);
|
||||
return [RACSignal empty];
|
||||
}]
|
||||
return [[[[[[[[self
|
||||
performHousekeeping]
|
||||
then:^{
|
||||
self.state = SQRLUpdaterStateCheckingForUpdate;
|
||||
|
||||
@@ -365,12 +328,20 @@ static NSString * const SQRLUpdaterUniqueTemporaryDirectoryPrefix = @"update.";
|
||||
NSURL *zipDownloadURL = update.updateURL;
|
||||
NSMutableURLRequest *zipDownloadRequest = [NSMutableURLRequest requestWithURL:zipDownloadURL];
|
||||
[zipDownloadRequest setValue:@"application/zip" forHTTPHeaderField:@"Accept"];
|
||||
if (self.etag != nil) {
|
||||
[zipDownloadRequest setValue:self.etag forHTTPHeaderField:@"If-None-Match"];
|
||||
}
|
||||
|
||||
return [[[[NSURLConnection
|
||||
rac_sendAsynchronousRequest:zipDownloadRequest]
|
||||
reduceEach:^(NSURLResponse *response, NSData *bodyData) {
|
||||
if ([response isKindOfClass:NSHTTPURLResponse.class]) {
|
||||
NSHTTPURLResponse *httpResponse = (id)response;
|
||||
|
||||
if (httpResponse.statusCode == 304 /* Not Modified */) {
|
||||
return [RACSignal empty];
|
||||
}
|
||||
|
||||
if (!(httpResponse.statusCode >= 200 && httpResponse.statusCode <= 299)) {
|
||||
NSDictionary *errorInfo = @{
|
||||
NSLocalizedDescriptionKey: NSLocalizedString(@"Update download failed", nil),
|
||||
@@ -380,6 +351,8 @@ static NSString * const SQRLUpdaterUniqueTemporaryDirectoryPrefix = @"update.";
|
||||
NSError *error = [NSError errorWithDomain:SQRLUpdaterErrorDomain code:SQRLUpdaterErrorInvalidServerResponse userInfo:errorInfo];
|
||||
return [RACSignal error:error];
|
||||
}
|
||||
|
||||
self.etag = httpResponse.allHeaderFields[@"ETag"];
|
||||
}
|
||||
|
||||
return [RACSignal return:bodyData];
|
||||
@@ -421,10 +394,10 @@ static NSString * const SQRLUpdaterUniqueTemporaryDirectoryPrefix = @"update.";
|
||||
return [[[RACSignal
|
||||
defer:^{
|
||||
SQRLDirectoryManager *directoryManager = [[SQRLDirectoryManager alloc] initWithApplicationIdentifier:SQRLShipItLauncher.shipItJobLabel];
|
||||
return [directoryManager applicationSupportURL];
|
||||
return [directoryManager storageURL];
|
||||
}]
|
||||
flattenMap:^(NSURL *appSupportURL) {
|
||||
NSURL *updateDirectoryTemplate = [appSupportURL URLByAppendingPathComponent:[SQRLUpdaterUniqueTemporaryDirectoryPrefix stringByAppendingString:@"XXXXXXX"]];
|
||||
flattenMap:^(NSURL *storageURL) {
|
||||
NSURL *updateDirectoryTemplate = [storageURL URLByAppendingPathComponent:[SQRLUpdaterUniqueTemporaryDirectoryPrefix stringByAppendingString:@"XXXXXXX"]];
|
||||
char *updateDirectoryCString = strdup(updateDirectoryTemplate.path.fileSystemRepresentation);
|
||||
@onExit {
|
||||
free(updateDirectoryCString);
|
||||
@@ -502,6 +475,84 @@ static NSString * const SQRLUpdaterUniqueTemporaryDirectoryPrefix = @"update.";
|
||||
setNameWithFormat:@"%@ -shipItStateURL", self];
|
||||
}
|
||||
|
||||
- (RACSignal *)performHousekeeping {
|
||||
return [[RACSignal
|
||||
merge:@[ [self pruneUpdateDirectories], [self truncateLogs] ]]
|
||||
catch:^(NSError *error) {
|
||||
NSLog(@"Error doing housekeeping: %@", error);
|
||||
return [RACSignal empty];
|
||||
}];
|
||||
}
|
||||
|
||||
/// Lazily removes outdated temporary directories (used for previous updates)
|
||||
/// upon subscription.
|
||||
///
|
||||
/// Pruning directories while an update is pending or in progress will result in
|
||||
/// undefined behavior.
|
||||
///
|
||||
/// Sends each removed directory then completes, or errors, on an unspecified
|
||||
/// thread.
|
||||
- (RACSignal *)pruneUpdateDirectories {
|
||||
return [[[RACSignal
|
||||
defer:^{
|
||||
SQRLDirectoryManager *directoryManager = [[SQRLDirectoryManager alloc] initWithApplicationIdentifier:SQRLShipItLauncher.shipItJobLabel];
|
||||
return [directoryManager storageURL];
|
||||
}]
|
||||
flattenMap:^(NSURL *storageURL) {
|
||||
NSFileManager *manager = [[NSFileManager alloc] init];
|
||||
NSDirectoryEnumerator *enumerator = [manager enumeratorAtURL:storageURL includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsSubdirectoryDescendants errorHandler:^(NSURL *URL, NSError *error) {
|
||||
NSLog(@"Error enumerating item %@ within directory %@: %@", URL, storageURL, error);
|
||||
return YES;
|
||||
}];
|
||||
|
||||
return [[enumerator.rac_sequence.signal
|
||||
filter:^(NSURL *enumeratedURL) {
|
||||
NSString *name = enumeratedURL.lastPathComponent;
|
||||
return [name hasPrefix:SQRLUpdaterUniqueTemporaryDirectoryPrefix];
|
||||
}]
|
||||
doNext:^(NSURL *directoryURL) {
|
||||
NSError *error = nil;
|
||||
if (![manager removeItemAtURL:directoryURL error:&error]) {
|
||||
NSLog(@"Error removing old update directory at %@: %@", directoryURL, error.sqrl_verboseDescription);
|
||||
}
|
||||
}];
|
||||
}]
|
||||
setNameWithFormat:@"%@ -prunedUpdateDirectories", self];
|
||||
}
|
||||
|
||||
|
||||
// Like truncation, but backwards.
|
||||
- (RACSignal *)backwardTruncateFile:(NSURL *)fileURL {
|
||||
return [RACSignal defer:^{
|
||||
static const NSInteger MAX_LENGTH = 1024 * 1024 * 8;
|
||||
|
||||
NSError *error;
|
||||
NSFileHandle *handle = [NSFileHandle fileHandleForWritingToURL:fileURL error:&error];
|
||||
if (handle == nil) return [RACSignal error:error];
|
||||
|
||||
unsigned long long fileLength = [handle seekToEndOfFile];
|
||||
if (fileLength <= MAX_LENGTH) return [RACSignal empty];
|
||||
|
||||
[handle seekToFileOffset:fileLength - MAX_LENGTH];
|
||||
NSData *mostRecentData = [handle readDataToEndOfFile];
|
||||
[handle truncateFileAtOffset:0];
|
||||
[handle writeData:mostRecentData];
|
||||
|
||||
return [RACSignal empty];
|
||||
}];
|
||||
}
|
||||
|
||||
- (RACSignal *)truncateLogs {
|
||||
return [[RACSignal
|
||||
defer:^{
|
||||
SQRLDirectoryManager *directoryManager = [[SQRLDirectoryManager alloc] initWithApplicationIdentifier:SQRLShipItLauncher.shipItJobLabel];
|
||||
return [RACSignal zip:@[ [directoryManager shipItStdoutURL], [directoryManager shipItStderrURL] ]];
|
||||
}]
|
||||
reduceEach:^(NSURL *stdoutURL, NSURL *stderrURL) {
|
||||
return [RACSignal merge:@[ [self backwardTruncateFile:stdoutURL], [self backwardTruncateFile:stderrURL] ]];
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark Installing Updates
|
||||
|
||||
- (RACSignal *)verifyAndPrepareUpdate:(SQRLUpdate *)update fromBundle:(NSBundle *)updateBundle {
|
||||
|
||||
@@ -123,7 +123,7 @@ static void installRequest(RACSignal *readRequestSignal, SQRLDirectoryManager *d
|
||||
}
|
||||
|
||||
NSError *error;
|
||||
if (![NSWorkspace.sharedWorkspace launchApplicationAtURL:bundleURL options:NSWorkspaceLaunchDefault configuration:nil error:&error]) {
|
||||
if (![NSWorkspace.sharedWorkspace launchApplicationAtURL:bundleURL options:NSWorkspaceLaunchDefault configuration:@{} error:&error]) {
|
||||
NSLog(@"Could not launch application at %@: %@", bundleURL, error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.github.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
#import <Squirrel/Squirrel.h>
|
||||
|
||||
/// See https://github.com/Squirrel/Squirrel.Mac/pull/154#issuecomment-151287744
|
||||
#define SKIP_IF_RUNNING_ON_TRAVIS if (self.runningOnTravis) return;
|
||||
|
||||
// The short version string for the `testApplicationBundle`.
|
||||
extern NSString * const SQRLTestApplicationOriginalShortVersionString;
|
||||
|
||||
@@ -21,6 +24,10 @@ extern NSString * const SQRLTestApplicationUpdatedShortVersionString;
|
||||
// The Info.plist key associated with a bundle's short version string.
|
||||
extern NSString * const SQRLBundleShortVersionStringKey;
|
||||
|
||||
/// The longer timeout we should use for things that take a long time. This is
|
||||
/// especially needed on slower machines (e.g., Travis CI).
|
||||
extern const NSTimeInterval SQRLLongTimeout;
|
||||
|
||||
@class SQRLCodeSignature;
|
||||
@class SQRLDirectoryManager;
|
||||
@class SQRLShipItRequest;
|
||||
@@ -54,6 +61,9 @@ extern NSString * const SQRLBundleShortVersionStringKey;
|
||||
// A directory manager for finding URLs that apply to ShipIt.
|
||||
@property (nonatomic, strong, readonly) SQRLDirectoryManager *shipItDirectoryManager;
|
||||
|
||||
/// Are the tests currently being run on Travis?
|
||||
@property (nonatomic, readonly, assign, getter = isRunningOnTravis) BOOL runningOnTravis;
|
||||
|
||||
// Launches a new copy of TestApplication.app from the `testApplicationBundle`.
|
||||
//
|
||||
// Invoking this method multiple times will result in multiple running instances
|
||||
|
||||
@@ -23,6 +23,8 @@ NSString * const SQRLTestApplicationOriginalShortVersionString = @"1.0";
|
||||
NSString * const SQRLTestApplicationUpdatedShortVersionString = @"2.1";
|
||||
NSString * const SQRLBundleShortVersionStringKey = @"CFBundleShortVersionString";
|
||||
|
||||
const NSTimeInterval SQRLLongTimeout = 20;
|
||||
|
||||
static void SQRLKillAllTestApplications(void) {
|
||||
// Forcibly kill all copies of the TestApplication that may be running.
|
||||
NSArray *apps = [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.github.Squirrel.TestApplication"];
|
||||
@@ -43,24 +45,6 @@ static void SQRLSignalHandler(int sig) {
|
||||
abort();
|
||||
}
|
||||
|
||||
// Returns an _unlaunched_ task that will follow log files at the given paths,
|
||||
// then pipe that output through this process.
|
||||
static NSTask *SQRLTailTaskWithPaths(RACSequence *paths) {
|
||||
NSPipe *outputPipe = [NSPipe pipe];
|
||||
NSFileHandle *outputHandle = outputPipe.fileHandleForReading;
|
||||
|
||||
outputHandle.readabilityHandler = ^(NSFileHandle *handle) {
|
||||
NSString *output = [[NSString alloc] initWithData:handle.availableData encoding:NSUTF8StringEncoding];
|
||||
NSLog(@"\n%@", output);
|
||||
};
|
||||
|
||||
NSTask *task = [[NSTask alloc] init];
|
||||
task.launchPath = @"/usr/bin/tail";
|
||||
task.standardOutput = outputPipe;
|
||||
task.arguments = [[paths startWith:@"-f"] array];
|
||||
return task;
|
||||
}
|
||||
|
||||
static NSBundle *SQRLTestBundle(void) {
|
||||
return [NSBundle bundleWithIdentifier:@"com.github.SquirrelTests"];
|
||||
}
|
||||
@@ -90,12 +74,6 @@ QuickConfigurationBegin(Fixtures)
|
||||
].rac_sequence;
|
||||
}];
|
||||
|
||||
RACSequence *paths = [URLs map:^(NSURL *URL) {
|
||||
return URL.path;
|
||||
}];
|
||||
|
||||
NSTask *readShipIt = SQRLTailTaskWithPaths(paths);
|
||||
|
||||
[configuration beforeSuite:^{
|
||||
signal(SIGILL, &SQRLSignalHandler);
|
||||
NSSetUncaughtExceptionHandler(&SQRLUncaughtExceptionHandler);
|
||||
@@ -108,14 +86,6 @@ QuickConfigurationBegin(Fixtures)
|
||||
NSLog(@"Could not touch log file at %@", URL);
|
||||
}
|
||||
}
|
||||
|
||||
[readShipIt launch];
|
||||
|
||||
NSAssert([readShipIt isRunning], @"Could not start task %@", readShipIt);
|
||||
}];
|
||||
|
||||
[configuration afterSuite:^{
|
||||
[readShipIt terminate];
|
||||
}];
|
||||
|
||||
// We want to run any enqueued cleanup blocks after _and before_ each spec,
|
||||
@@ -193,15 +163,6 @@ QuickConfigurationEnd
|
||||
|
||||
NSURL *testAppLog = [fixtureURL.URLByDeletingLastPathComponent URLByAppendingPathComponent:@"TestApplication.log"];
|
||||
[[NSData data] writeToURL:testAppLog atomically:YES];
|
||||
|
||||
NSTask *readTestApp = SQRLTailTaskWithPaths([RACSequence return:testAppLog.path]);
|
||||
[readTestApp launch];
|
||||
|
||||
XCTAssertTrue([readTestApp isRunning], @"Could not start task %@ to read %@", readTestApp, testAppLog);
|
||||
|
||||
[self addCleanupBlock:^{
|
||||
[readTestApp terminate];
|
||||
}];
|
||||
}
|
||||
|
||||
return fixtureURL;
|
||||
@@ -365,6 +326,10 @@ QuickConfigurationEnd
|
||||
return [NSURL fileURLWithPath:path isDirectory:YES];
|
||||
}
|
||||
|
||||
- (BOOL)isRunningOnTravis {
|
||||
return NSProcessInfo.processInfo.environment[@"TRAVIS"] != nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
//
|
||||
// SQRLDeepCodesignSpec.m
|
||||
// Squirrel
|
||||
//
|
||||
// Created by Keith Duncan on 2013-09-05.
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Nimble/Nimble.h>
|
||||
#import <Quick/Quick.h>
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
#import <Squirrel/Squirrel.h>
|
||||
|
||||
#import "QuickSpec+SQRLFixtures.h"
|
||||
|
||||
QuickSpecBegin(SQRLDeepCodesign)
|
||||
|
||||
NSMutableDictionary * (^environmentSuitableForChildProcess)(void) = ^ {
|
||||
// Remove environment variables that configure the Obj-C runtime
|
||||
// Specifically OBJC_DISABLE_GC so that child processes aren't forced to
|
||||
// adopt the GC preference of the test suite
|
||||
NSMutableDictionary *environment = [NSProcessInfo.processInfo.environment mutableCopy];
|
||||
NSSet *objcEnvironmentVariables = [environment keysOfEntriesPassingTest:^(NSString *variable, id obj, BOOL *stop) {
|
||||
return [variable hasPrefix:@"OBJC"];
|
||||
}];
|
||||
[environment removeObjectsForKeys:objcEnvironmentVariables.allObjects];
|
||||
return environment;
|
||||
};
|
||||
|
||||
NSTask * (^codesignTaskWithArguments)(NSArray *) = ^ (NSArray *arguments) {
|
||||
NSTask *task = [[NSTask alloc] init];
|
||||
task.launchPath = @"/usr/bin/xcrun";
|
||||
task.arguments = [@[ @"codesign" ] arrayByAddingObjectsFromArray:arguments];
|
||||
task.environment = environmentSuitableForChildProcess();
|
||||
return task;
|
||||
};
|
||||
|
||||
void (^resignTestApplicationPreserveEverythingButTheRequirements)(void) = ^{
|
||||
NSURL *testApplicationLocation = self.testApplicationURL;
|
||||
|
||||
NSTask *resignCodesignTask = codesignTaskWithArguments(@[
|
||||
@"--sign", @"-",
|
||||
@"--force",
|
||||
@"--verbose=4",
|
||||
@"--preserve-metadata=identifier,entitlements,resource-rules",
|
||||
testApplicationLocation.path,
|
||||
]);
|
||||
|
||||
[resignCodesignTask launch];
|
||||
[resignCodesignTask waitUntilExit];
|
||||
|
||||
expect(@(resignCodesignTask.terminationStatus)).to(equal(@0));
|
||||
};
|
||||
|
||||
void (^deepCodesignTestApplication)(void) = ^{
|
||||
NSURL *testApplicationLocation = self.testApplicationURL;
|
||||
|
||||
NSBundle *testsBundle = [NSBundle bundleForClass:self.class];
|
||||
NSURL *deepCodesignLocation = [testsBundle URLForResource:@"deep-codesign" withExtension:nil];
|
||||
|
||||
NSNumber *executable = nil;
|
||||
NSError *executableError = nil;
|
||||
BOOL getExecutable = [deepCodesignLocation getResourceValue:&executable forKey:NSURLIsExecutableKey error:&executableError];
|
||||
expect(@(getExecutable)).to(beTruthy());
|
||||
expect(@(executable.boolValue)).to(beTruthy());
|
||||
expect(executableError).to(beNil());
|
||||
|
||||
NSTask *deepCodesignTask = [[NSTask alloc] init];
|
||||
deepCodesignTask.launchPath = deepCodesignLocation.path;
|
||||
deepCodesignTask.standardError = [NSPipe pipe];
|
||||
deepCodesignTask.standardOutput = [NSPipe pipe];
|
||||
|
||||
NSMutableDictionary *environment = environmentSuitableForChildProcess();
|
||||
[environment addEntriesFromDictionary:@{
|
||||
@"CODE_SIGN_IDENTITY": @"-",
|
||||
@"CONFIGURATION_BUILD_DIR": testApplicationLocation.URLByDeletingLastPathComponent.path,
|
||||
@"FULL_PRODUCT_NAME": testApplicationLocation.lastPathComponent,
|
||||
}];
|
||||
|
||||
deepCodesignTask.environment = environment;
|
||||
|
||||
[deepCodesignTask launch];
|
||||
[deepCodesignTask waitUntilExit];
|
||||
|
||||
expect(@(deepCodesignTask.terminationStatus)).to(equal(@0));
|
||||
|
||||
/*
|
||||
By signing test application's contents, which are covered by test
|
||||
application's ResourceRules it's signature becomes invalid. Usually,
|
||||
Xcode would sign the application after deep-codesign has run so the
|
||||
signature would include the _signed_ child resources which are covered
|
||||
by test application's ResourceRules
|
||||
|
||||
test application is already signed, so we need to manually resign it
|
||||
|
||||
deep-codesign preserves the requirements, we can't use it to resign the
|
||||
root target, the new signing identity wouldn't verify against the
|
||||
original designated requirement
|
||||
*/
|
||||
resignTestApplicationPreserveEverythingButTheRequirements();
|
||||
};
|
||||
|
||||
BOOL (^deepVerify)(void) = ^ BOOL {
|
||||
NSTask *deepVerifyTask = codesignTaskWithArguments(@[
|
||||
@"--deep-verify",
|
||||
@"--verbose=4",
|
||||
self.testApplicationURL.path
|
||||
]);
|
||||
|
||||
[deepVerifyTask launch];
|
||||
[deepVerifyTask waitUntilExit];
|
||||
|
||||
return deepVerifyTask.terminationStatus == 0;
|
||||
};
|
||||
|
||||
it(@"should deep sign the test application", ^{
|
||||
deepCodesignTestApplication();
|
||||
});
|
||||
|
||||
xit(@"should deep verify after signing", ^{
|
||||
expect(@(deepVerify())).to(beFalsy());
|
||||
deepCodesignTestApplication();
|
||||
expect(@(deepVerify())).to(beTruthy());
|
||||
});
|
||||
|
||||
QuickSpecEnd
|
||||
@@ -37,7 +37,7 @@ it(@"should send an Application Support URL", ^{
|
||||
SQRLDirectoryManager *manager = SQRLDirectoryManager.currentApplicationManager;
|
||||
|
||||
NSError *error = nil;
|
||||
NSURL *appSupportURL = [[manager applicationSupportURL] firstOrDefault:nil success:NULL error:&error];
|
||||
NSURL *appSupportURL = [[manager storageURL] firstOrDefault:nil success:NULL error:&error];
|
||||
expect(appSupportURL).notTo(beNil());
|
||||
expect(error).to(beNil());
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ it(@"should install an update to another volume", ^{
|
||||
[self installWithRequest:request remote:YES];
|
||||
|
||||
NSURL *plistURL = [targetURL URLByAppendingPathComponent:@"Contents/Info.plist"];
|
||||
expect([NSDictionary dictionaryWithContentsOfURL:plistURL][SQRLBundleShortVersionStringKey]).toEventually(equal(SQRLTestApplicationUpdatedShortVersionString));
|
||||
expect([NSDictionary dictionaryWithContentsOfURL:plistURL][SQRLBundleShortVersionStringKey]).withTimeout(SQRLLongTimeout).toEventually(equal(SQRLTestApplicationUpdatedShortVersionString));
|
||||
});
|
||||
|
||||
describe(@"with backup restoration", ^{
|
||||
@@ -133,7 +133,7 @@ describe(@"with backup restoration", ^{
|
||||
[self installWithRequest:request remote:YES];
|
||||
|
||||
expect(@([NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.github.Squirrel.TestApplication"].count)).toEventually(equal(@1));
|
||||
|
||||
|
||||
__block NSError *error;
|
||||
expect(@([[self.testApplicationSignature verifyBundleAtURL:targetURL] waitUntilCompleted:&error])).to(beTruthy());
|
||||
expect(error).to(beNil());
|
||||
@@ -165,7 +165,7 @@ describe(@"signal handling", ^{
|
||||
void (^verifyUpdate)(void) = ^{
|
||||
// Wait up to the launchd throttle interval, then verify that ShipIt
|
||||
// relaunched and finished installing the update.
|
||||
expect(self.testApplicationBundleVersion).withTimeout(5).toEventually(equal(SQRLTestApplicationUpdatedShortVersionString));
|
||||
expect(self.testApplicationBundleVersion).withTimeout(SQRLLongTimeout).toEventually(equal(SQRLTestApplicationUpdatedShortVersionString));
|
||||
|
||||
NSError *error;
|
||||
BOOL success = [[self.testApplicationSignature verifyBundleAtURL:targetURL] waitUntilCompleted:&error];
|
||||
|
||||
@@ -34,6 +34,8 @@ it(@"should complete immediately when the app is not running", ^{
|
||||
});
|
||||
|
||||
it(@"should wait until one instance terminates", ^{
|
||||
SKIP_IF_RUNNING_ON_TRAVIS
|
||||
|
||||
NSRunningApplication *app = [self launchTestApplicationWithEnvironment:nil];
|
||||
|
||||
__block NSRunningApplication *observedApp = nil;
|
||||
@@ -53,6 +55,8 @@ it(@"should wait until one instance terminates", ^{
|
||||
});
|
||||
|
||||
it(@"should wait until multiple instances terminate", ^{
|
||||
SKIP_IF_RUNNING_ON_TRAVIS
|
||||
|
||||
NSRunningApplication *app1 = [self launchTestApplicationWithEnvironment:nil];
|
||||
NSRunningApplication *app2 = [self launchTestApplicationWithEnvironment:nil];
|
||||
|
||||
|
||||
@@ -45,12 +45,12 @@ it(@"should validate release name and notes", ^{
|
||||
|
||||
it(@"should parse Central style dates", ^{
|
||||
SQRLUpdate *update = [MTLJSONAdapter modelOfClass:SQRLUpdate.class fromJSONDictionary:@{ @"url": @"http://example.com/update", @"pub_date": @"Tue Sep 17 10:24:27 -0700 2013" } error:NULL];
|
||||
expect(update.releaseDate).notTo(beNil());
|
||||
expect(update.releaseDate).to(equal([NSDate dateWithTimeIntervalSince1970:1379438667]));
|
||||
});
|
||||
|
||||
it(@"should parse ISO 8601 dates", ^{
|
||||
SQRLUpdate *update = [MTLJSONAdapter modelOfClass:SQRLUpdate.class fromJSONDictionary:@{ @"url": @"http://example.com/update", @"pub_date": @"2013-09-18T13:17:07+01:00" } error:NULL];
|
||||
expect(update.releaseDate).notTo(beNil());
|
||||
expect(update.releaseDate).to(equal([NSDate dateWithTimeIntervalSince1970:1379506627]));
|
||||
});
|
||||
|
||||
QuickSpecEnd
|
||||
|
||||
@@ -67,6 +67,8 @@ describe(@"updating", ^{
|
||||
});
|
||||
|
||||
it(@"should use the application's bundled version of Squirrel and update in-place", ^{
|
||||
SKIP_IF_RUNNING_ON_TRAVIS
|
||||
|
||||
NSError *error = nil;
|
||||
SQRLTestUpdate *update = [SQRLTestUpdate modelWithDictionary:@{
|
||||
@"updateURL": zipUpdate(updateURL),
|
||||
@@ -78,11 +80,13 @@ describe(@"updating", ^{
|
||||
writeUpdate(update);
|
||||
|
||||
NSRunningApplication *app = launchWithEnvironment(nil);
|
||||
expect(@(app.terminated)).toEventually(beTruthy());
|
||||
expect(@(app.terminated)).withTimeout(SQRLLongTimeout).toEventually(beTruthy());
|
||||
expect(self.testApplicationBundleVersion).toEventually(equal(SQRLTestApplicationUpdatedShortVersionString));
|
||||
});
|
||||
|
||||
it(@"should not install a corrupt update", ^{
|
||||
SKIP_IF_RUNNING_ON_TRAVIS
|
||||
|
||||
NSURL *codeSignatureURL = [updateURL URLByAppendingPathComponent:@"Contents/_CodeSignature"];
|
||||
expect(@([NSFileManager.defaultManager removeItemAtURL:codeSignatureURL error:NULL])).to(beTruthy());
|
||||
|
||||
@@ -94,7 +98,7 @@ describe(@"updating", ^{
|
||||
writeUpdate(update);
|
||||
|
||||
NSRunningApplication *app = launchWithEnvironment(nil);
|
||||
expect(@(app.terminated)).withTimeout(5).toEventually(beTruthy());
|
||||
expect(@(app.terminated)).withTimeout(SQRLLongTimeout).toEventually(beTruthy());
|
||||
|
||||
// Give the update some time to finish installing.
|
||||
[NSThread sleepForTimeInterval:0.2];
|
||||
@@ -102,6 +106,8 @@ describe(@"updating", ^{
|
||||
});
|
||||
|
||||
it(@"should update to the most recently enqueued job", ^{
|
||||
SKIP_IF_RUNNING_ON_TRAVIS
|
||||
|
||||
SQRLTestUpdate *update = [SQRLTestUpdate modelWithDictionary:@{
|
||||
@"updateURL": zipUpdate(self.testApplicationURL)
|
||||
} error:NULL];
|
||||
@@ -125,11 +131,13 @@ describe(@"updating", ^{
|
||||
|
||||
writeUpdate(update);
|
||||
|
||||
expect(@(app.terminated)).withTimeout(5).toEventually(beTruthy());
|
||||
expect(@(app.terminated)).withTimeout(SQRLLongTimeout).toEventually(beTruthy());
|
||||
expect(self.testApplicationBundleVersion).toEventually(equal(SQRLTestApplicationUpdatedShortVersionString));
|
||||
});
|
||||
|
||||
it(@"should use the application's bundled version of Squirrel and update in-place after a significant delay", ^{
|
||||
SKIP_IF_RUNNING_ON_TRAVIS
|
||||
|
||||
SQRLTestUpdate *update = [SQRLTestUpdate modelWithDictionary:@{
|
||||
@"updateURL": zipUpdate(updateURL),
|
||||
@"final": @YES
|
||||
@@ -140,7 +148,7 @@ describe(@"updating", ^{
|
||||
NSTimeInterval delay = 15;
|
||||
NSRunningApplication *app = launchWithEnvironment(@{ @"SQRLUpdateDelay": [NSString stringWithFormat:@"%f", delay] });
|
||||
|
||||
expect(@(app.terminated)).withTimeout(delay + 5).toEventually(beTruthy());
|
||||
expect(@(app.terminated)).withTimeout(delay + SQRLLongTimeout).toEventually(beTruthy());
|
||||
expect(self.testApplicationBundleVersion).toEventually(equal(SQRLTestApplicationUpdatedShortVersionString));
|
||||
});
|
||||
|
||||
@@ -151,7 +159,7 @@ describe(@"updating", ^{
|
||||
beforeEach(^{
|
||||
SQRLDirectoryManager *directoryManager = [[SQRLDirectoryManager alloc] initWithApplicationIdentifier:@"com.github.Squirrel.TestApplication.ShipIt"];
|
||||
|
||||
appSupportURL = [[directoryManager applicationSupportURL] first];
|
||||
appSupportURL = [[directoryManager storageURL] first];
|
||||
expect(appSupportURL).notTo(beNil());
|
||||
|
||||
updateDirectoryURLs = [[RACSignal
|
||||
@@ -167,6 +175,8 @@ describe(@"updating", ^{
|
||||
});
|
||||
|
||||
it(@"should remove downloaded archives after updating", ^{
|
||||
SKIP_IF_RUNNING_ON_TRAVIS
|
||||
|
||||
NSError *error = nil;
|
||||
SQRLTestUpdate *update = [SQRLTestUpdate modelWithDictionary:@{
|
||||
@"updateURL": zipUpdate(updateURL),
|
||||
@@ -178,8 +188,9 @@ describe(@"updating", ^{
|
||||
|
||||
writeUpdate(update);
|
||||
|
||||
NSRunningApplication *app = launchWithEnvironment(nil);
|
||||
expect(@(app.terminated)).withTimeout(5).toEventually(beTruthy());
|
||||
NSRunningApplication *app = launchWithEnvironment(@{ @"SQRLUpdateRequestCount": @2 });
|
||||
expect([updateDirectoryURLs toArray]).toEventuallyNot(equal(@[]));
|
||||
expect(@(app.terminated)).withTimeout(SQRLLongTimeout).toEventually(beTruthy());
|
||||
expect(self.testApplicationBundleVersion).toEventually(equal(SQRLTestApplicationUpdatedShortVersionString));
|
||||
|
||||
expect([updateDirectoryURLs toArray]).toEventually(equal(@[]));
|
||||
@@ -242,6 +253,8 @@ static RACSignal * (^stateNotificationListener)(void) = ^ {
|
||||
|
||||
describe(@"state", ^{
|
||||
it(@"should transition through idle, checking and idle, when there is no update", ^{
|
||||
SKIP_IF_RUNNING_ON_TRAVIS
|
||||
|
||||
NSMutableArray *states = [NSMutableArray array];
|
||||
[stateNotificationListener() subscribeNext:^(NSNumber *state) {
|
||||
[states addObject:state];
|
||||
@@ -256,10 +269,12 @@ describe(@"state", ^{
|
||||
];
|
||||
expect(states).toEventually(equal(expectedStates));
|
||||
|
||||
expect(@(testApplication.terminated)).withTimeout(5).toEventually(beTruthy());
|
||||
expect(@(testApplication.terminated)).withTimeout(SQRLLongTimeout).toEventually(beTruthy());
|
||||
});
|
||||
|
||||
it(@"should transition through idle, checking, downloading and awaiting relaunch, when there is an update", ^{
|
||||
SKIP_IF_RUNNING_ON_TRAVIS
|
||||
|
||||
NSMutableArray *states = [NSMutableArray array];
|
||||
[stateNotificationListener() subscribeNext:^(NSNumber *state) {
|
||||
[states addObject:state];
|
||||
@@ -283,9 +298,9 @@ describe(@"state", ^{
|
||||
@(SQRLUpdaterStateDownloadingUpdate),
|
||||
@(SQRLUpdaterStateAwaitingRelaunch),
|
||||
];
|
||||
expect(states).toEventually(equal(expectedStates));
|
||||
expect(states).withTimeout(SQRLLongTimeout).toEventually(equal(expectedStates));
|
||||
|
||||
expect(@(testApplication.terminated)).withTimeout(5).toEventually(beTruthy());
|
||||
expect(@(testApplication.terminated)).withTimeout(SQRLLongTimeout).toEventually(beTruthy());
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.github.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>rules</key>
|
||||
<dict>
|
||||
<key>.*</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -72,6 +72,9 @@
|
||||
|
||||
__block NSUInteger updateCheckCount = 1;
|
||||
|
||||
NSInteger updateRequestCount = [NSProcessInfo.processInfo.environment[@"SQRLUpdateRequestCount"] integerValue];
|
||||
if (updateRequestCount < 1) updateRequestCount = 1;
|
||||
|
||||
[[[[[[[[[[RACSignal
|
||||
defer:^{
|
||||
NSLog(@"***** UPDATE CHECK %lu *****", (unsigned long)updateCheckCount);
|
||||
@@ -90,7 +93,7 @@
|
||||
|
||||
return testUpdate.final;
|
||||
}]
|
||||
take:1]
|
||||
take:updateRequestCount]
|
||||
doNext:^(id _) {
|
||||
NSLog(@"***** READY TO INSTALL UPDATE *****");
|
||||
}]
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.github.Squirrel.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
@@ -30,5 +30,7 @@
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>NSSupportsAutomaticTermination</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
|
||||
Binary file not shown.
+9
-13
@@ -41,30 +41,26 @@ config ()
|
||||
# Individual names can be quoted to avoid word splitting.
|
||||
: ${SCHEMES:=Squirrel}
|
||||
|
||||
# A source-able file with information about the Keychain, containing our
|
||||
# code-signing certificate.
|
||||
: ${KEYCHAIN_INFO:=/var/lib/jenkins/config/xcodekeychain}
|
||||
|
||||
export XCWORKSPACE
|
||||
export XCODEPROJ
|
||||
export BOOTSTRAP
|
||||
export XCTOOL_OPTIONS
|
||||
export SCHEMES
|
||||
export KEYCHAIN_INFO
|
||||
}
|
||||
|
||||
##
|
||||
## Code Signing
|
||||
##
|
||||
|
||||
unlock_keychain ()
|
||||
setup_keychain ()
|
||||
{
|
||||
if [ -e "$KEYCHAIN_INFO" ]
|
||||
then
|
||||
# Unlock the keychain so the certificates it contains can be used for building.
|
||||
. "$KEYCHAIN_INFO"
|
||||
security unlock-keychain -p "$XCODE_KEYCHAIN_PASSWORD" "$XCODE_KEYCHAIN"
|
||||
fi
|
||||
KEY_CHAIN=build.keychain
|
||||
security create-keychain -p travis $KEY_CHAIN
|
||||
|
||||
security default-keychain -s $KEY_CHAIN
|
||||
security unlock-keychain -p travis $KEY_CHAIN
|
||||
security set-keychain-settings -t 3600 -u $KEY_CHAIN
|
||||
security import script/certs.p12 -k build.keychain -P $KEY_PASSWORD -T /usr/bin/codesign
|
||||
}
|
||||
|
||||
##
|
||||
@@ -74,7 +70,7 @@ unlock_keychain ()
|
||||
main ()
|
||||
{
|
||||
config
|
||||
unlock_keychain
|
||||
setup_keychain
|
||||
|
||||
if [ -f "$BOOTSTRAP" ]
|
||||
then
|
||||
|
||||
@@ -1,203 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
def exit_error(description)
|
||||
puts "{ \"error\": \"#{description}\" }"
|
||||
exit 1
|
||||
end
|
||||
|
||||
module Targets
|
||||
class Object
|
||||
def self.match(path)
|
||||
!File.symlink?(path)
|
||||
end
|
||||
|
||||
attr_reader :path
|
||||
|
||||
def initialize(path)
|
||||
@path = path
|
||||
end
|
||||
|
||||
def search_directories
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
class Bundle < Object
|
||||
def self.match(path)
|
||||
return false unless super
|
||||
|
||||
return false unless match = File.extname(path).match(/\.(.+)/)
|
||||
return match[1] == extension
|
||||
end
|
||||
|
||||
def contents_directories
|
||||
[ "Contents" ]
|
||||
end
|
||||
|
||||
def suffix_directories
|
||||
[
|
||||
"Frameworks",
|
||||
"SharedFrameworks",
|
||||
"XPCServices",
|
||||
"PlugIns",
|
||||
"Support",
|
||||
"SharedSupport",
|
||||
File.join("Library", "LoginItems"),
|
||||
File.join("Library", "LaunchServices"),
|
||||
]
|
||||
end
|
||||
|
||||
def search_directories
|
||||
contents_directories.product(suffix_directories).map do |combination|
|
||||
File.join(*combination)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class VersionedBundle < Bundle
|
||||
def contents_directories
|
||||
contents_directories = []
|
||||
versions_directory = File.join(@path, "Versions")
|
||||
Dir.foreach(versions_directory) do |current_version|
|
||||
next if current_version.start_with?('.')
|
||||
|
||||
full_path = File.join(versions_directory, current_version)
|
||||
next if File.symlink?(full_path)
|
||||
|
||||
contents_directories << File.join("Versions", current_version)
|
||||
end
|
||||
contents_directories
|
||||
end
|
||||
end
|
||||
|
||||
class App < Bundle
|
||||
def self.extension
|
||||
"app"
|
||||
end
|
||||
end
|
||||
|
||||
class Framework < VersionedBundle
|
||||
def self.extension
|
||||
"framework"
|
||||
end
|
||||
end
|
||||
|
||||
class XPCService < Bundle
|
||||
def self.extension
|
||||
"xpc"
|
||||
end
|
||||
end
|
||||
|
||||
class Tool < Object
|
||||
def self.match(path)
|
||||
return false unless super
|
||||
return false unless File.executable?(path)
|
||||
|
||||
# Look for an __TEXT,__info_plist section
|
||||
# This contains the CFBundleIdentifier necessary for signing
|
||||
`otool -l #{path}` =~ /__info_plist/
|
||||
end
|
||||
end
|
||||
|
||||
def self.all_targets
|
||||
[ App, Framework, XPCService, Tool ]
|
||||
end
|
||||
end
|
||||
|
||||
module Codesign
|
||||
class Task
|
||||
def self.sign(target, identity, timestamp)
|
||||
arguments = [ "--sign", identity, "--force", "--preserve-metadata=identifier,entitlements,requirements", "--verbose", target.path ]
|
||||
arguments.unshift("--timestamp=none") if not timestamp
|
||||
codesign_with_arguments(arguments)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def self.codesign_with_arguments(arguments)
|
||||
$stdout.flush
|
||||
|
||||
pid = fork
|
||||
if pid.nil?
|
||||
exec("/usr/bin/xcrun", *([ "codesign" ].concat(arguments)))
|
||||
else
|
||||
Process.wait(pid)
|
||||
exit_error("codesign failed") unless $?.exitstatus == 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
codesign_identity = ENV['CODE_SIGN_IDENTITY']
|
||||
unless codesign_identity
|
||||
exit_error("No codesign identity provided")
|
||||
end
|
||||
|
||||
build_dir = ENV['CONFIGURATION_BUILD_DIR']
|
||||
product_name = ENV['FULL_PRODUCT_NAME']
|
||||
unless build_dir && product_name
|
||||
exit_error("Path to built product not provided")
|
||||
end
|
||||
|
||||
input_path = File.realpath(File.join(build_dir, product_name))
|
||||
unless File.exists?(input_path)
|
||||
exit_error("Built product doesn't exist at path provided")
|
||||
end
|
||||
|
||||
targets = [ ]
|
||||
|
||||
def match_path(path)
|
||||
Targets.all_targets.each do |target|
|
||||
return target.new(path) if target.match(path)
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
root_target = match_path input_path
|
||||
if root_target.nil?
|
||||
exit_error("Built product is not a known file structure, cannot deep codesign")
|
||||
end
|
||||
|
||||
# Recursion base case can't use build_dir because there can be >1 product
|
||||
paths_to_search = root_target.search_directories.map do |current_dir|
|
||||
File.join(root_target.path, current_dir)
|
||||
end
|
||||
|
||||
while paths_to_search.size > 0
|
||||
new_search_paths = []
|
||||
paths_to_search.each do |search_path|
|
||||
next unless File.directory?(search_path)
|
||||
|
||||
Dir.foreach(search_path) do |current_directory_entry|
|
||||
next if current_directory_entry.start_with?(".")
|
||||
File.delete(File.join(search_path, current_directory_entry)) if current_directory_entry.end_with?(".cstemp")
|
||||
|
||||
target = match_path(File.join(search_path, current_directory_entry))
|
||||
next if target.nil?
|
||||
|
||||
targets << target
|
||||
|
||||
new_search_paths << target.search_directories.map do |current_search_directory|
|
||||
File.join(target.path, current_search_directory)
|
||||
end
|
||||
end
|
||||
end
|
||||
paths_to_search = new_search_paths.flatten
|
||||
end
|
||||
|
||||
puts "Signing these targets:"
|
||||
puts "="*22
|
||||
print "\n"
|
||||
|
||||
# Sort into nested-most first, outer targets might include inner targets
|
||||
# in their ResourceRules
|
||||
targets = targets.sort_by do |target|
|
||||
target.path.size
|
||||
end
|
||||
targets.reverse!
|
||||
|
||||
use_timestamp = ENV["CONFIGURATION"] == "Release"
|
||||
targets.each do |target|
|
||||
puts "=> #{target.path}"
|
||||
Codesign::Task.sign(target, codesign_identity, use_timestamp)
|
||||
end
|
||||
Reference in New Issue
Block a user