Compare commits
177
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9e2188cda | ||
|
|
413b1d2bca | ||
|
|
d92d385431 | ||
|
|
9ebfd397fd | ||
|
|
7dffc4b143 | ||
|
|
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 | ||
|
|
8eb2517d6b | ||
|
|
46e044726f | ||
|
|
b30ee65933 | ||
|
|
ae89c0a1f6 | ||
|
|
54f765b19e | ||
|
|
d8a1185c6b | ||
|
|
dbf430683f | ||
|
|
d0634fc8e6 | ||
|
|
178648f373 | ||
|
|
3a4428cfb3 | ||
|
|
dab5bf2892 | ||
|
|
e3aa7a6767 | ||
|
|
0c8394f6f4 | ||
|
|
6779322eea | ||
|
|
5d8ffc9070 | ||
|
|
72345d4c18 | ||
|
|
52a6dc2fd2 | ||
|
|
5b05c23877 | ||
|
|
81c0841201 | ||
|
|
747e183b98 | ||
|
|
62a39671fc | ||
|
|
3be9c89f49 | ||
|
|
ceb4f34827 | ||
|
|
22e785a637 | ||
|
|
221519e3ad | ||
|
|
7faed9ec18 | ||
|
|
c74ecf9c07 | ||
|
|
04233f8f7c | ||
|
|
378e3891bf | ||
|
|
9e040347f5 | ||
|
|
c99ce7dfbb | ||
|
|
6b017d5d3f | ||
|
|
b1f4ecf615 | ||
|
|
fd29bc392f | ||
|
|
61b5ceb1cb | ||
|
|
38a8914b55 | ||
|
|
ede35f29d8 | ||
|
|
7e8abd13c4 | ||
|
|
d776817d8d | ||
|
|
82d79b65c3 | ||
|
|
8cf49c6fef | ||
|
|
caba5b81af | ||
|
|
98efd568df | ||
|
|
0e729b3725 | ||
|
|
190ac7a2b0 | ||
|
|
7e91d04b28 | ||
|
|
c43df8037b | ||
|
|
5471b65a4a | ||
|
|
37d3b3f802 | ||
|
|
bd9abf504d | ||
|
|
f415391772 | ||
|
|
c29fee075d | ||
|
|
bcd5433733 | ||
|
|
c0df5b1d57 | ||
|
|
f61a35ab42 | ||
|
|
0575de80c6 | ||
|
|
2a60c9c0f3 | ||
|
|
d9fe18f95e | ||
|
|
c7ea0aedb8 | ||
|
|
f340c9cb41 | ||
|
|
8babde1e71 | ||
|
|
e5685ac806 | ||
|
|
7597115f53 | ||
|
|
8a4a52fb2c | ||
|
|
775afe32c9 | ||
|
|
c4d487ea41 | ||
|
|
23d4e3e3ce | ||
|
|
3e6d0bf55c | ||
|
|
446ebb4501 | ||
|
|
656f742bee | ||
|
|
f91f53c545 | ||
|
|
4a8004be83 | ||
|
|
970343b9ee | ||
|
|
70dc382f8d | ||
|
|
c53a20d4de | ||
|
|
3a462922f4 | ||
|
|
38840a492e | ||
|
|
70ace5c15b | ||
|
|
6ef1b62d44 | ||
|
|
3b9e8e6243 | ||
|
|
21ffa5a45a | ||
|
|
55e4c5c42e | ||
|
|
38cd714fd2 | ||
|
|
dd69adc9ff | ||
|
|
cb07313ca7 | ||
|
|
ef930ca242 | ||
|
|
f30b68945c | ||
|
|
31c0abff54 | ||
|
|
4ca24da5ea | ||
|
|
43a7614322 | ||
|
|
453b8697f9 | ||
|
|
693d513354 | ||
|
|
9488a4cd12 | ||
|
|
a9ea214d11 | ||
|
|
6d91340ffa | ||
|
|
e8851b59bc | ||
|
|
9539744417 | ||
|
|
19b011bee5 | ||
|
|
6ca74dc2c7 | ||
|
|
cb2d4ecfd2 | ||
|
|
81c8b56e52 | ||
|
|
c245afac29 | ||
|
|
106e95b41f |
+19
-6
@@ -1,9 +1,22 @@
|
||||
[submodule "External/ReactiveCocoa"]
|
||||
path = External/ReactiveCocoa
|
||||
url = https://github.com/ReactiveCocoa/ReactiveCocoa.git
|
||||
[submodule "External/Mantle"]
|
||||
path = External/Mantle
|
||||
url = https://github.com/MantleFramework/Mantle.git
|
||||
[submodule "External/OHHTTPStubs"]
|
||||
path = External/OHHTTPStubs
|
||||
url = https://github.com/github/OHHTTPStubs
|
||||
[submodule "Carthage.checkout/Nimble"]
|
||||
path = Carthage/Checkouts/Nimble
|
||||
url = https://github.com/Quick/Nimble.git
|
||||
[submodule "Carthage.checkout/ReactiveCocoa"]
|
||||
path = Carthage/Checkouts/ReactiveCocoa
|
||||
url = https://github.com/ReactiveCocoa/ReactiveCocoa.git
|
||||
[submodule "Carthage.checkout/Quick"]
|
||||
path = Carthage/Checkouts/Quick
|
||||
url = https://github.com/Quick/Quick.git
|
||||
[submodule "Carthage.checkout/xcconfigs"]
|
||||
path = Carthage/Checkouts/xcconfigs
|
||||
url = https://github.com/jspahrsummers/xcconfigs.git
|
||||
[submodule "Carthage.checkout/Mantle"]
|
||||
path = Carthage/Checkouts/Mantle
|
||||
url = https://github.com/Mantle/Mantle.git
|
||||
[submodule "Carthage/Checkouts/Nimble"]
|
||||
url = https://github.com/Quick/Nimble.git
|
||||
[submodule "Carthage/Checkouts/Quick"]
|
||||
url = https://github.com/Quick/Quick.git
|
||||
|
||||
+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=
|
||||
@@ -0,0 +1,2 @@
|
||||
github "Mantle/Mantle" ~> 1.5.3
|
||||
github "ReactiveCocoa/ReactiveCocoa" ~> 2.4.3
|
||||
@@ -0,0 +1,3 @@
|
||||
github "jspahrsummers/xcconfigs" >= 0.7.1
|
||||
github "Quick/Quick" ~> 0.7
|
||||
github "Quick/Nimble" ~> 2.0
|
||||
@@ -0,0 +1,5 @@
|
||||
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"
|
||||
+1
Submodule Carthage/Checkouts/Mantle added at e41221ee94
+1
Submodule Carthage/Checkouts/Nimble added at 20a3f3b4e6
+1
Submodule Carthage/Checkouts/Quick added at 7d0b8c2135
+1
Submodule Carthage/Checkouts/ReactiveCocoa added at 32364b9040
+1
Submodule Carthage/Checkouts/xcconfigs added at 99624a6af3
Vendored
-1
Submodule External/Mantle deleted from fe3a65987b
Vendored
-1
Submodule External/ReactiveCocoa deleted from 16c181bbe8
@@ -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
|
||||
@@ -39,7 +40,7 @@ If you’re developing Squirrel on its own, then use `Squirrel.xcworkspace`.
|
||||
# Dependencies
|
||||
|
||||
Squirrel depends on [ReactiveCocoa](http://github.com/ReactiveCocoa/ReactiveCocoa)
|
||||
and [Mantle](https://github.com/MantleFramework/Mantle).
|
||||
and [Mantle](https://github.com/Mantle/Mantle).
|
||||
|
||||
If your application is already using ReactiveCocoa, ensure it is using the same
|
||||
version as Squirrel.
|
||||
@@ -113,12 +114,18 @@ To know when an update is ready to be installed, you can subscribe to the
|
||||
}];
|
||||
```
|
||||
|
||||
If you've been notified of an available update, and don't want to wait for it to
|
||||
be installed automatically, you can terminate the app to begin the installation
|
||||
process immediately.
|
||||
## Installing Updates
|
||||
|
||||
If you want to install a downloaded update and automatically relaunch afterward,
|
||||
`SQRLUpdater` can do that:
|
||||
While downloaded updates are automatically installed when your application
|
||||
terminates, if don't want to wait you can manually terminate the app to begin
|
||||
the installation process immediately.
|
||||
|
||||
Once an [update available notification](#update-available-notifications) has
|
||||
been received, you may want to present an interface informing the user about
|
||||
the update and offering the ability to install and relaunch.
|
||||
|
||||
To explicitly install a downloaded update and automatically relaunch afterward,
|
||||
subscribe to the `relaunchToInstallUpdate` signal on `SQRLUpdater`:
|
||||
|
||||
```objc
|
||||
[[self.updater relaunchToInstallUpdate] subscribeError:^(NSError *error) {
|
||||
@@ -152,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"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -169,4 +176,4 @@ appropriate format.
|
||||
|
||||
Squirrel does not provide any GUI components for presenting updates. If you want
|
||||
to indicate updates to the user, make sure to [listen for downloaded
|
||||
updates](#update-notifications).
|
||||
updates](#update-available-notifications).
|
||||
|
||||
+378
-141
@@ -8,13 +8,11 @@
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
533076EB17EB688300BDCCE0 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D097B9BC17BB4777006C3FEB /* IOKit.framework */; };
|
||||
534FF35B17D8E8B90020A51A /* unused-helper in Copy LoginItems */ = {isa = PBXBuildFile; fileRef = D0B1DDCB17B487D90059C355 /* unused-helper */; };
|
||||
534FF35B17D8E8B90020A51A /* unused-helper in Copy LoginItems */ = {isa = PBXBuildFile; fileRef = D0B1DDCB17B487D90059C355 /* unused-helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
534FF36117D8E90A0020A51A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F60CA7EA179FC4F60069F69A /* Foundation.framework */; };
|
||||
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 */; };
|
||||
53710D7417D8F59700A992DE /* SQRLDeepCodesignSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 53710D7317D8F59700A992DE /* SQRLDeepCodesignSpec.m */; };
|
||||
53710D8417D8F5CB00A992DE /* deep-codesign in Resources */ = {isa = PBXBuildFile; fileRef = 53710D7F17D8F5C300A992DE /* deep-codesign */; };
|
||||
534FF37317D8E9370020A51A /* com.github.Squirrel.TestApplication.TestService.xpc in Copy XPCServices */ = {isa = PBXBuildFile; fileRef = 534FF36017D8E90A0020A51A /* com.github.Squirrel.TestApplication.TestService.xpc */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
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,9 +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 */; };
|
||||
BE312944196B999300F1A675 /* SQRLTestHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = BE312943196B999300F1A675 /* SQRLTestHelper.m */; };
|
||||
BE31BEA0196B74A900376A76 /* libSpecta-OSX.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BE31BE9F196B74A900376A76 /* libSpecta-OSX.a */; };
|
||||
BE31BEA1196B74B000376A76 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0366C1C17B18FEE0086ED44 /* XCTest.framework */; };
|
||||
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 */; };
|
||||
@@ -40,7 +37,7 @@
|
||||
D014ABBA17B97403007D79D0 /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D014ABB917B97403007D79D0 /* ServiceManagement.framework */; };
|
||||
D014AC0517B97885007D79D0 /* ShipIt-main.m in Sources */ = {isa = PBXBuildFile; fileRef = D014AC0417B97885007D79D0 /* ShipIt-main.m */; };
|
||||
D014AC1117B9789C007D79D0 /* SQRLInstaller.m in Sources */ = {isa = PBXBuildFile; fileRef = D014AC1017B9789C007D79D0 /* SQRLInstaller.m */; };
|
||||
D014AC1817B97945007D79D0 /* ShipIt in Copy ShipIt */ = {isa = PBXBuildFile; fileRef = D014AC0117B97885007D79D0 /* ShipIt */; };
|
||||
D014AC1817B97945007D79D0 /* ShipIt in Copy ShipIt */ = {isa = PBXBuildFile; fileRef = D014AC0117B97885007D79D0 /* ShipIt */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
D014AC1917B979A8007D79D0 /* SQRLCodeSignature.m in Sources */ = {isa = PBXBuildFile; fileRef = F6F2ED8217A33C4900F4D220 /* SQRLCodeSignature.m */; };
|
||||
D014AC1A17B979AA007D79D0 /* NSError+SQRLVerbosityExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = D0EDBE9B17B0C68E0058BC3C /* NSError+SQRLVerbosityExtensions.m */; };
|
||||
D014AC1D17B979B7007D79D0 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6EB217F179D0E4D001108CF /* Security.framework */; };
|
||||
@@ -58,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 */; };
|
||||
@@ -65,7 +63,7 @@
|
||||
D08D4E1C17B451500012B22D /* TestAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D08D4E1B17B451500012B22D /* TestAppDelegate.m */; };
|
||||
D08D4E2117B451500012B22D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D08D4E2017B451500012B22D /* Images.xcassets */; };
|
||||
D08D4E4717B451E50012B22D /* Squirrel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0C22BD7179CC00E00158214 /* Squirrel.framework */; };
|
||||
D08D4E4917B451F20012B22D /* Squirrel.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = D0C22BD7179CC00E00158214 /* Squirrel.framework */; };
|
||||
D08D4E4917B451F20012B22D /* Squirrel.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = D0C22BD7179CC00E00158214 /* Squirrel.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
D08D4E4A17B451FD0012B22D /* TestApplication.app in Resources */ = {isa = PBXBuildFile; fileRef = D08D4E0C17B451500012B22D /* TestApplication.app */; };
|
||||
D093682417FF732200BA0EAE /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D014ABB917B97403007D79D0 /* ServiceManagement.framework */; };
|
||||
D0964B3817F2E01500D88BF7 /* SQRLDownloadedUpdate.h in Headers */ = {isa = PBXBuildFile; fileRef = D0964B3617F2E01500D88BF7 /* SQRLDownloadedUpdate.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@@ -74,37 +72,91 @@
|
||||
D0964B3D17F2E20B00D88BF7 /* NSBundle+SQRLVersionExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = D0964B3B17F2E20B00D88BF7 /* NSBundle+SQRLVersionExtensions.m */; };
|
||||
D0964B3E17F2E20B00D88BF7 /* NSBundle+SQRLVersionExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = D0964B3B17F2E20B00D88BF7 /* NSBundle+SQRLVersionExtensions.m */; };
|
||||
D097B9BD17BB4777006C3FEB /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D097B9BC17BB4777006C3FEB /* IOKit.framework */; };
|
||||
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 */; };
|
||||
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 */; };
|
||||
D09C663B1A00538D007D7ED0 /* RACObjCRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = D09C663A1A00538D007D7ED0 /* RACObjCRuntime.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
|
||||
D09C663D1A0053C6007D7ED0 /* NSString+RACKeyPathUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = D09C663C1A0053C6007D7ED0 /* NSString+RACKeyPathUtilities.m */; };
|
||||
D09C663F1A005433007D7ED0 /* NSEnumerator+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D09C663E1A005433007D7ED0 /* NSEnumerator+RACSequenceAdditions.m */; };
|
||||
D09C66411A005592007D7ED0 /* MTLModel+NSCoding.m in Sources */ = {isa = PBXBuildFile; fileRef = D09C66401A005592007D7ED0 /* MTLModel+NSCoding.m */; };
|
||||
D09C66461A0055E6007D7ED0 /* NSArray+MTLManipulationAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D09C66421A0055E6007D7ED0 /* NSArray+MTLManipulationAdditions.m */; };
|
||||
D09C66471A0055E6007D7ED0 /* NSDictionary+MTLManipulationAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D09C66431A0055E6007D7ED0 /* NSDictionary+MTLManipulationAdditions.m */; };
|
||||
D09C66481A0055E6007D7ED0 /* NSError+MTLModelException.m in Sources */ = {isa = PBXBuildFile; fileRef = D09C66441A0055E6007D7ED0 /* NSError+MTLModelException.m */; };
|
||||
D09C66491A0055E6007D7ED0 /* NSObject+MTLComparisonAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D09C66451A0055E6007D7ED0 /* NSObject+MTLComparisonAdditions.m */; };
|
||||
D09C664B1A0055F3007D7ED0 /* NSValueTransformer+MTLInversionAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D09C664A1A0055F3007D7ED0 /* NSValueTransformer+MTLInversionAdditions.m */; };
|
||||
D09D244117B595470001FAF8 /* SQRLInstallerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D09D244017B595470001FAF8 /* SQRLInstallerSpec.m */; };
|
||||
D09D244A17B59AB30001FAF8 /* TestApplication 2.1.app in Resources */ = {isa = PBXBuildFile; fileRef = D09D244917B59AB30001FAF8 /* TestApplication 2.1.app */; };
|
||||
D0A6D2BC17B9FA9E00B2C3DF /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6EB217F179D0E4D001108CF /* Security.framework */; };
|
||||
D0B1DDCE17B487FB0059C355 /* unused-helper in Copy Executables */ = {isa = PBXBuildFile; fileRef = D0B1DDCB17B487D90059C355 /* unused-helper */; };
|
||||
D0AFE33B1A00282C00C6048F /* MTLJSONAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3381A00282C00C6048F /* MTLJSONAdapter.m */; };
|
||||
D0AFE33C1A00282C00C6048F /* MTLModel.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3391A00282C00C6048F /* MTLModel.m */; };
|
||||
D0AFE33D1A00282C00C6048F /* MTLValueTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE33A1A00282C00C6048F /* MTLValueTransformer.m */; };
|
||||
D0AFE3431A00285000C6048F /* MTLReflection.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3411A00285000C6048F /* MTLReflection.m */; };
|
||||
D0AFE3441A00285000C6048F /* NSValueTransformer+MTLPredefinedTransformerAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3421A00285000C6048F /* NSValueTransformer+MTLPredefinedTransformerAdditions.m */; };
|
||||
D0AFE34A1A00287100C6048F /* RACCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3451A00287100C6048F /* RACCommand.m */; };
|
||||
D0AFE34B1A00287100C6048F /* RACDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3461A00287100C6048F /* RACDisposable.m */; };
|
||||
D0AFE34C1A00287100C6048F /* RACScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3471A00287100C6048F /* RACScheduler.m */; };
|
||||
D0AFE34D1A00287100C6048F /* RACSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3481A00287100C6048F /* RACSignal.m */; };
|
||||
D0AFE34E1A00287100C6048F /* RACSignal+Operations.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3491A00287100C6048F /* RACSignal+Operations.m */; };
|
||||
D0AFE3651A0028A400C6048F /* RACBlockTrampoline.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE34F1A0028A400C6048F /* RACBlockTrampoline.m */; };
|
||||
D0AFE3661A0028A400C6048F /* RACCompoundDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3501A0028A400C6048F /* RACCompoundDisposable.m */; };
|
||||
D0AFE3671A0028A400C6048F /* RACDynamicSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3511A0028A400C6048F /* RACDynamicSignal.m */; };
|
||||
D0AFE3681A0028A400C6048F /* RACEmptySequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3521A0028A400C6048F /* RACEmptySequence.m */; };
|
||||
D0AFE3691A0028A400C6048F /* RACEmptySignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3531A0028A400C6048F /* RACEmptySignal.m */; };
|
||||
D0AFE36A1A0028A400C6048F /* RACErrorSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3541A0028A400C6048F /* RACErrorSignal.m */; };
|
||||
D0AFE36B1A0028A400C6048F /* RACEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3551A0028A400C6048F /* RACEvent.m */; };
|
||||
D0AFE36C1A0028A400C6048F /* RACGroupedSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3561A0028A400C6048F /* RACGroupedSignal.m */; };
|
||||
D0AFE36D1A0028A400C6048F /* RACImmediateScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3571A0028A400C6048F /* RACImmediateScheduler.m */; };
|
||||
D0AFE36E1A0028A400C6048F /* RACMulticastConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3581A0028A400C6048F /* RACMulticastConnection.m */; };
|
||||
D0AFE36F1A0028A400C6048F /* RACReplaySubject.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3591A0028A400C6048F /* RACReplaySubject.m */; };
|
||||
D0AFE3701A0028A400C6048F /* RACReturnSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE35A1A0028A400C6048F /* RACReturnSignal.m */; };
|
||||
D0AFE3711A0028A400C6048F /* RACScopedDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE35B1A0028A400C6048F /* RACScopedDisposable.m */; };
|
||||
D0AFE3721A0028A400C6048F /* RACSerialDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE35C1A0028A400C6048F /* RACSerialDisposable.m */; };
|
||||
D0AFE3731A0028A400C6048F /* RACSignalSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE35D1A0028A400C6048F /* RACSignalSequence.m */; };
|
||||
D0AFE3741A0028A400C6048F /* RACStream.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE35E1A0028A400C6048F /* RACStream.m */; };
|
||||
D0AFE3751A0028A400C6048F /* RACSubject.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE35F1A0028A400C6048F /* RACSubject.m */; };
|
||||
D0AFE3761A0028A400C6048F /* RACSubscriber.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3601A0028A400C6048F /* RACSubscriber.m */; };
|
||||
D0AFE3771A0028A400C6048F /* RACSubscriptionScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3611A0028A400C6048F /* RACSubscriptionScheduler.m */; };
|
||||
D0AFE3781A0028A400C6048F /* RACTargetQueueScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3621A0028A400C6048F /* RACTargetQueueScheduler.m */; };
|
||||
D0AFE3791A0028A400C6048F /* RACTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3631A0028A400C6048F /* RACTuple.m */; };
|
||||
D0AFE37A1A0028A400C6048F /* RACUnit.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3641A0028A400C6048F /* RACUnit.m */; };
|
||||
D0AFE37C1A0028B000C6048F /* RACCompoundDisposableProvider.d in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE37B1A0028B000C6048F /* RACCompoundDisposableProvider.d */; };
|
||||
D0AFE3811A0028CC00C6048F /* RACPassthroughSubscriber.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE37D1A0028CC00C6048F /* RACPassthroughSubscriber.m */; };
|
||||
D0AFE3821A0028CC00C6048F /* RACQueueScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE37E1A0028CC00C6048F /* RACQueueScheduler.m */; };
|
||||
D0AFE3831A0028CC00C6048F /* RACSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE37F1A0028CC00C6048F /* RACSequence.m */; };
|
||||
D0AFE3841A0028CC00C6048F /* RACTupleSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3801A0028CC00C6048F /* RACTupleSequence.m */; };
|
||||
D0AFE3861A0028D500C6048F /* RACSignalProvider.d in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3851A0028D500C6048F /* RACSignalProvider.d */; };
|
||||
D0AFE38B1A0028EC00C6048F /* RACArraySequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3871A0028EC00C6048F /* RACArraySequence.m */; };
|
||||
D0AFE38C1A0028EC00C6048F /* RACDynamicSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3881A0028EC00C6048F /* RACDynamicSequence.m */; };
|
||||
D0AFE38D1A0028EC00C6048F /* RACEagerSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE3891A0028EC00C6048F /* RACEagerSequence.m */; };
|
||||
D0AFE38E1A0028EC00C6048F /* RACUnarySequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE38A1A0028EC00C6048F /* RACUnarySequence.m */; };
|
||||
D0AFE3901A00294100C6048F /* SwiftSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AFE38F1A00294100C6048F /* SwiftSpec.swift */; };
|
||||
D0AFE3931A00297500C6048F /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0AFE3921A00297500C6048F /* Quick.framework */; };
|
||||
D0AFE3951A0029A700C6048F /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0AFE3941A0029A700C6048F /* Nimble.framework */; };
|
||||
D0B1DDCE17B487FB0059C355 /* unused-helper in Copy Executables */ = {isa = PBXBuildFile; fileRef = D0B1DDCB17B487D90059C355 /* unused-helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
D0C22BDB179CC00E00158214 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0C22BDA179CC00E00158214 /* Cocoa.framework */; };
|
||||
D0C22BE5179CC00E00158214 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D0C22BE3179CC00E00158214 /* InfoPlist.strings */; };
|
||||
D0C22BF2179CC00E00158214 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0C22BDA179CC00E00158214 /* Cocoa.framework */; };
|
||||
D0C22BF5179CC00E00158214 /* Squirrel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0C22BD7179CC00E00158214 /* Squirrel.framework */; };
|
||||
D0C22BFB179CC00E00158214 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D0C22BF9179CC00E00158214 /* InfoPlist.strings */; };
|
||||
D0C22C4C179CC15100158214 /* SQRLUpdater.h in Headers */ = {isa = PBXBuildFile; fileRef = D0C22C4A179CC15100158214 /* SQRLUpdater.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D0C22C4D179CC15100158214 /* SQRLUpdater.m in Sources */ = {isa = PBXBuildFile; fileRef = D0C22C4B179CC15100158214 /* SQRLUpdater.m */; };
|
||||
D0C22C50179CC18C00158214 /* SQRLUpdaterSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D0C22C4F179CC18C00158214 /* SQRLUpdaterSpec.m */; };
|
||||
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 /* SQRLTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = D0EDBEDC17B0DB3E0058BC3C /* SQRLTestCase.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 */; };
|
||||
D45F1A9218E46F2E005CE515 /* ReactiveCocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4C4909A18E46DFE00786EFE /* ReactiveCocoa.framework */; };
|
||||
D45F1A9318E46F2E005CE515 /* Mantle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4C4909818E46DE900786EFE /* Mantle.framework */; };
|
||||
D45F1A9418E47055005CE515 /* ReactiveCocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4C4909A18E46DFE00786EFE /* ReactiveCocoa.framework */; };
|
||||
D45F1A9518E47055005CE515 /* Mantle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4C4909818E46DE900786EFE /* Mantle.framework */; };
|
||||
D4ACA4F618DB9CCB00EBD899 /* libExpecta.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4ACA4F518DB9CCB00EBD899 /* libExpecta.a */; };
|
||||
D4ACA50118DB9F3F00EBD899 /* OHHTTPStubs.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4ACA50018DB9F3F00EBD899 /* OHHTTPStubs.framework */; };
|
||||
D4C4909918E46DE900786EFE /* Mantle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4C4909818E46DE900786EFE /* Mantle.framework */; };
|
||||
D4C4909B18E46DFE00786EFE /* ReactiveCocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4C4909A18E46DFE00786EFE /* ReactiveCocoa.framework */; };
|
||||
D4C4909E18E46E1000786EFE /* ReactiveCocoa.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = D4C4909A18E46DFE00786EFE /* ReactiveCocoa.framework */; };
|
||||
D4C4909F18E46E1000786EFE /* Mantle.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = D4C4909818E46DE900786EFE /* Mantle.framework */; };
|
||||
D4C490A118E46E8200786EFE /* libMantle-Mac.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4C490A018E46E8200786EFE /* libMantle-Mac.a */; };
|
||||
D4C490A318E46E8800786EFE /* libReactiveCocoa-Mac.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4C490A218E46E8800786EFE /* libReactiveCocoa-Mac.a */; };
|
||||
D4C4909E18E46E1000786EFE /* ReactiveCocoa.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = D4C4909A18E46DFE00786EFE /* ReactiveCocoa.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
D4C4909F18E46E1000786EFE /* Mantle.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = D4C4909818E46DE900786EFE /* Mantle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
F6EB2162179CFD93001108CF /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6EB2161179CFD93001108CF /* SystemConfiguration.framework */; };
|
||||
F6EB2180179D0E4D001108CF /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6EB217F179D0E4D001108CF /* Security.framework */; };
|
||||
F6F2ED8417A33C4900F4D220 /* SQRLCodeSignature.m in Sources */ = {isa = PBXBuildFile; fileRef = F6F2ED8217A33C4900F4D220 /* SQRLCodeSignature.m */; };
|
||||
@@ -214,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>"; };
|
||||
@@ -234,9 +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>"; };
|
||||
BE312942196B999300F1A675 /* SQRLTestHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQRLTestHelper.h; sourceTree = "<group>"; };
|
||||
BE312943196B999300F1A675 /* SQRLTestHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQRLTestHelper.m; sourceTree = "<group>"; };
|
||||
BE31BE9F196B74A900376A76 /* libSpecta-OSX.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libSpecta-OSX.a"; path = "External/ReactiveCocoa/external/specta/build/Debug/libSpecta-OSX.a"; 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>"; };
|
||||
@@ -254,7 +307,6 @@
|
||||
D0366C0017B18FEE0086ED44 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
D0366C0117B18FEE0086ED44 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
|
||||
D0366C0217B18FEE0086ED44 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
D0366C1C17B18FEE0086ED44 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
|
||||
D03BE98C17B6174500458593 /* MainMenu.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = "<group>"; };
|
||||
D043F77017FF40C90012F996 /* SQRLTerminationListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQRLTerminationListener.h; sourceTree = "<group>"; };
|
||||
D043F77117FF40C90012F996 /* SQRLTerminationListener.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQRLTerminationListener.m; sourceTree = "<group>"; };
|
||||
@@ -265,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>"; };
|
||||
@@ -279,18 +332,77 @@
|
||||
D0964B3A17F2E20B00D88BF7 /* NSBundle+SQRLVersionExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBundle+SQRLVersionExtensions.h"; sourceTree = "<group>"; };
|
||||
D0964B3B17F2E20B00D88BF7 /* NSBundle+SQRLVersionExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSBundle+SQRLVersionExtensions.m"; sourceTree = "<group>"; };
|
||||
D097B9BC17BB4777006C3FEB /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
|
||||
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; };
|
||||
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; };
|
||||
D09C663A1A00538D007D7ED0 /* RACObjCRuntime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACObjCRuntime.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACObjCRuntime.m; sourceTree = SOURCE_ROOT; };
|
||||
D09C663C1A0053C6007D7ED0 /* NSString+RACKeyPathUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSString+RACKeyPathUtilities.m"; path = "Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/NSString+RACKeyPathUtilities.m"; sourceTree = SOURCE_ROOT; };
|
||||
D09C663E1A005433007D7ED0 /* NSEnumerator+RACSequenceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSEnumerator+RACSequenceAdditions.m"; path = "Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/NSEnumerator+RACSequenceAdditions.m"; sourceTree = SOURCE_ROOT; };
|
||||
D09C66401A005592007D7ED0 /* MTLModel+NSCoding.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "MTLModel+NSCoding.m"; path = "Carthage/Checkouts/Mantle/Mantle/MTLModel+NSCoding.m"; sourceTree = SOURCE_ROOT; };
|
||||
D09C66421A0055E6007D7ED0 /* NSArray+MTLManipulationAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSArray+MTLManipulationAdditions.m"; path = "Carthage/Checkouts/Mantle/Mantle/NSArray+MTLManipulationAdditions.m"; sourceTree = SOURCE_ROOT; };
|
||||
D09C66431A0055E6007D7ED0 /* NSDictionary+MTLManipulationAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+MTLManipulationAdditions.m"; path = "Carthage/Checkouts/Mantle/Mantle/NSDictionary+MTLManipulationAdditions.m"; sourceTree = SOURCE_ROOT; };
|
||||
D09C66441A0055E6007D7ED0 /* NSError+MTLModelException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSError+MTLModelException.m"; path = "Carthage/Checkouts/Mantle/Mantle/NSError+MTLModelException.m"; sourceTree = SOURCE_ROOT; };
|
||||
D09C66451A0055E6007D7ED0 /* NSObject+MTLComparisonAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSObject+MTLComparisonAdditions.m"; path = "Carthage/Checkouts/Mantle/Mantle/NSObject+MTLComparisonAdditions.m"; sourceTree = SOURCE_ROOT; };
|
||||
D09C664A1A0055F3007D7ED0 /* NSValueTransformer+MTLInversionAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSValueTransformer+MTLInversionAdditions.m"; path = "Carthage/Checkouts/Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.m"; sourceTree = SOURCE_ROOT; };
|
||||
D09D244017B595470001FAF8 /* SQRLInstallerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQRLInstallerSpec.m; sourceTree = "<group>"; };
|
||||
D09D244917B59AB30001FAF8 /* TestApplication 2.1.app */ = {isa = PBXFileReference; lastKnownFileType = wrapper.application; path = "TestApplication 2.1.app"; sourceTree = "<group>"; };
|
||||
D0AFE3351A00236E00C6048F /* Framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Framework.xcconfig; sourceTree = "<group>"; };
|
||||
D0AFE3361A00237400C6048F /* iOS-Framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "iOS-Framework.xcconfig"; sourceTree = "<group>"; };
|
||||
D0AFE3381A00282C00C6048F /* MTLJSONAdapter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MTLJSONAdapter.m; path = Carthage/Checkouts/Mantle/Mantle/MTLJSONAdapter.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3391A00282C00C6048F /* MTLModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MTLModel.m; path = Carthage/Checkouts/Mantle/Mantle/MTLModel.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE33A1A00282C00C6048F /* MTLValueTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MTLValueTransformer.m; path = Carthage/Checkouts/Mantle/Mantle/MTLValueTransformer.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3411A00285000C6048F /* MTLReflection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MTLReflection.m; path = Carthage/Checkouts/Mantle/Mantle/MTLReflection.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3421A00285000C6048F /* NSValueTransformer+MTLPredefinedTransformerAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSValueTransformer+MTLPredefinedTransformerAdditions.m"; path = "Carthage/Checkouts/Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.m"; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3451A00287100C6048F /* RACCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACCommand.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACCommand.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3461A00287100C6048F /* RACDisposable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACDisposable.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACDisposable.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3471A00287100C6048F /* RACScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACScheduler.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACScheduler.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3481A00287100C6048F /* RACSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACSignal.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACSignal.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3491A00287100C6048F /* RACSignal+Operations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "RACSignal+Operations.m"; path = "Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACSignal+Operations.m"; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE34F1A0028A400C6048F /* RACBlockTrampoline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACBlockTrampoline.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACBlockTrampoline.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3501A0028A400C6048F /* RACCompoundDisposable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACCompoundDisposable.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACCompoundDisposable.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3511A0028A400C6048F /* RACDynamicSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACDynamicSignal.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACDynamicSignal.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3521A0028A400C6048F /* RACEmptySequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACEmptySequence.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACEmptySequence.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3531A0028A400C6048F /* RACEmptySignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACEmptySignal.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACEmptySignal.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3541A0028A400C6048F /* RACErrorSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACErrorSignal.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACErrorSignal.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3551A0028A400C6048F /* RACEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACEvent.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACEvent.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3561A0028A400C6048F /* RACGroupedSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACGroupedSignal.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACGroupedSignal.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3571A0028A400C6048F /* RACImmediateScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACImmediateScheduler.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACImmediateScheduler.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3581A0028A400C6048F /* RACMulticastConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACMulticastConnection.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACMulticastConnection.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3591A0028A400C6048F /* RACReplaySubject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACReplaySubject.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACReplaySubject.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE35A1A0028A400C6048F /* RACReturnSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACReturnSignal.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACReturnSignal.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE35B1A0028A400C6048F /* RACScopedDisposable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACScopedDisposable.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACScopedDisposable.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE35C1A0028A400C6048F /* RACSerialDisposable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACSerialDisposable.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACSerialDisposable.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE35D1A0028A400C6048F /* RACSignalSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACSignalSequence.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACSignalSequence.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE35E1A0028A400C6048F /* RACStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACStream.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACStream.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE35F1A0028A400C6048F /* RACSubject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACSubject.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACSubject.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3601A0028A400C6048F /* RACSubscriber.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACSubscriber.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACSubscriber.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3611A0028A400C6048F /* RACSubscriptionScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACSubscriptionScheduler.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACSubscriptionScheduler.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3621A0028A400C6048F /* RACTargetQueueScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACTargetQueueScheduler.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACTargetQueueScheduler.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3631A0028A400C6048F /* RACTuple.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACTuple.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACTuple.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3641A0028A400C6048F /* RACUnit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACUnit.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACUnit.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE37B1A0028B000C6048F /* RACCompoundDisposableProvider.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; name = RACCompoundDisposableProvider.d; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACCompoundDisposableProvider.d; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE37D1A0028CC00C6048F /* RACPassthroughSubscriber.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACPassthroughSubscriber.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACPassthroughSubscriber.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE37E1A0028CC00C6048F /* RACQueueScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACQueueScheduler.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACQueueScheduler.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE37F1A0028CC00C6048F /* RACSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACSequence.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACSequence.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3801A0028CC00C6048F /* RACTupleSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACTupleSequence.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACTupleSequence.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3851A0028D500C6048F /* RACSignalProvider.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; name = RACSignalProvider.d; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACSignalProvider.d; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3871A0028EC00C6048F /* RACArraySequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACArraySequence.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACArraySequence.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3881A0028EC00C6048F /* RACDynamicSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACDynamicSequence.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACDynamicSequence.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE3891A0028EC00C6048F /* RACEagerSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACEagerSequence.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACEagerSequence.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE38A1A0028EC00C6048F /* RACUnarySequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RACUnarySequence.m; path = Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/RACUnarySequence.m; sourceTree = SOURCE_ROOT; };
|
||||
D0AFE38F1A00294100C6048F /* SwiftSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftSpec.swift; sourceTree = "<group>"; };
|
||||
D0AFE3921A00297500C6048F /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Quick.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D0AFE3941A0029A700C6048F /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Nimble.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D0B1DDCB17B487D90059C355 /* unused-helper */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = "unused-helper"; sourceTree = "<group>"; };
|
||||
D0C22BD7179CC00E00158214 /* Squirrel.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Squirrel.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D0C22BDA179CC00E00158214 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
D0C22BE2179CC00E00158214 /* Squirrel-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Squirrel-Info.plist"; sourceTree = "<group>"; };
|
||||
D0C22BE4179CC00E00158214 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
D0C22BE6179CC00E00158214 /* Squirrel-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Squirrel-Prefix.pch"; sourceTree = "<group>"; };
|
||||
D0C22BE7179CC00E00158214 /* Squirrel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Squirrel.h; sourceTree = "<group>"; };
|
||||
D0C22BEF179CC00E00158214 /* SquirrelTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SquirrelTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D0C22BF8179CC00E00158214 /* SquirrelTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SquirrelTests-Info.plist"; sourceTree = "<group>"; };
|
||||
D0C22BFA179CC00E00158214 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
D0C22C09179CC02E00158214 /* Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.xcconfig; sourceTree = "<group>"; };
|
||||
D0C22C0B179CC02E00158214 /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
|
||||
D0C22C0C179CC02E00158214 /* Profile.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Profile.xcconfig; sourceTree = "<group>"; };
|
||||
@@ -310,22 +422,16 @@
|
||||
D0C22C4A179CC15100158214 /* SQRLUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQRLUpdater.h; sourceTree = "<group>"; };
|
||||
D0C22C4B179CC15100158214 /* SQRLUpdater.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQRLUpdater.m; sourceTree = "<group>"; };
|
||||
D0C22C4F179CC18C00158214 /* SQRLUpdaterSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQRLUpdaterSpec.m; sourceTree = "<group>"; };
|
||||
D0C22C51179CC1A200158214 /* SquirrelTests-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SquirrelTests-Prefix.pch"; 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 /* SQRLTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQRLTestCase.h; sourceTree = "<group>"; };
|
||||
D0EDBEDC17B0DB3E0058BC3C /* SQRLTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQRLTestCase.m; sourceTree = "<group>"; };
|
||||
D0EDBEDB17B0DB3E0058BC3C /* QuickSpec+SQRLFixtures.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "QuickSpec+SQRLFixtures.h"; sourceTree = "<group>"; };
|
||||
D0EDBEDC17B0DB3E0058BC3C /* QuickSpec+SQRLFixtures.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "QuickSpec+SQRLFixtures.m"; sourceTree = "<group>"; };
|
||||
D0EDBEE017B0E3650058BC3C /* SQRLCodeSignatureSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQRLCodeSignatureSpec.m; sourceTree = "<group>"; };
|
||||
D4ACA4F518DB9CCB00EBD899 /* libExpecta.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libExpecta.a; path = External/ReactiveCocoa/external/expecta/build/Debug/libExpecta.a; sourceTree = "<group>"; };
|
||||
D4ACA4F718DB9CCE00EBD899 /* libSpecta.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libSpecta.a; path = External/ReactiveCocoa/external/specta/build/Debug/libSpecta.a; sourceTree = "<group>"; };
|
||||
D4ACA50018DB9F3F00EBD899 /* OHHTTPStubs.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OHHTTPStubs.framework; path = External/OHHTTPStubs/OHHTTPStubs/build/Debug/OHHTTPStubs.framework; sourceTree = "<group>"; };
|
||||
D4C4909818E46DE900786EFE /* Mantle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Mantle.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D4C4909A18E46DFE00786EFE /* ReactiveCocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = ReactiveCocoa.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D4C490A018E46E8200786EFE /* libMantle-Mac.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libMantle-Mac.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D4C490A218E46E8800786EFE /* libReactiveCocoa-Mac.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libReactiveCocoa-Mac.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F60CA7EA179FC4F60069F69A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
F65A915F17A71AA5005A4666 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
F6EB2161179CFD93001108CF /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
|
||||
@@ -351,8 +457,6 @@
|
||||
D014AC1F17B979C4007D79D0 /* Cocoa.framework in Frameworks */,
|
||||
D014AC1D17B979B7007D79D0 /* Security.framework in Frameworks */,
|
||||
D014AC1E17B979BD007D79D0 /* ServiceManagement.framework in Frameworks */,
|
||||
D4C490A118E46E8200786EFE /* libMantle-Mac.a in Frameworks */,
|
||||
D4C490A318E46E8800786EFE /* libReactiveCocoa-Mac.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -385,13 +489,12 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D0AFE3931A00297500C6048F /* Quick.framework in Frameworks */,
|
||||
D4ACA50118DB9F3F00EBD899 /* OHHTTPStubs.framework in Frameworks */,
|
||||
D093682417FF732200BA0EAE /* ServiceManagement.framework in Frameworks */,
|
||||
BE31BEA1196B74B000376A76 /* XCTest.framework in Frameworks */,
|
||||
BE31BEA0196B74A900376A76 /* libSpecta-OSX.a in Frameworks */,
|
||||
D4ACA4F618DB9CCB00EBD899 /* libExpecta.a in Frameworks */,
|
||||
D061E40317FD581C00CC134A /* IOKit.framework in Frameworks */,
|
||||
D0C22BF2179CC00E00158214 /* Cocoa.framework in Frameworks */,
|
||||
D0AFE3951A0029A700C6048F /* Nimble.framework in Frameworks */,
|
||||
D0A6D2BC17B9FA9E00B2C3DF /* Security.framework in Frameworks */,
|
||||
D0C22BF5179CC00E00158214 /* Squirrel.framework in Frameworks */,
|
||||
D45F1A9218E46F2E005CE515 /* ReactiveCocoa.framework in Frameworks */,
|
||||
@@ -427,7 +530,6 @@
|
||||
children = (
|
||||
53710D7D17D8F5C300A992DE /* bootstrap */,
|
||||
53710D7E17D8F5C300A992DE /* cibuild */,
|
||||
53710D7F17D8F5C300A992DE /* deep-codesign */,
|
||||
53710D8017D8F5C300A992DE /* LICENSE.md */,
|
||||
53710D8117D8F5C300A992DE /* README.md */,
|
||||
53710D8217D8F5C300A992DE /* targets.awk */,
|
||||
@@ -466,6 +568,7 @@
|
||||
D043F77117FF40C90012F996 /* SQRLTerminationListener.m */,
|
||||
5397A5EA187DA2570014A477 /* SQRLInstallerOwnedBundle.h */,
|
||||
5397A5EB187DA2570014A477 /* SQRLInstallerOwnedBundle.m */,
|
||||
D0AFE3371A00282000C6048F /* Static Dependencies */,
|
||||
);
|
||||
name = ShipIt;
|
||||
path = Squirrel;
|
||||
@@ -518,7 +621,6 @@
|
||||
D08D4E0F17B451500012B22D /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D0D97E4417B58FC400301C72 /* ResourceRules.plist */,
|
||||
D0B1DDCB17B487D90059C355 /* unused-helper */,
|
||||
D08D4E1017B451500012B22D /* TestApplication-Info.plist */,
|
||||
D08D4E1117B451500012B22D /* InfoPlist.strings */,
|
||||
@@ -581,6 +683,77 @@
|
||||
name = "Code Signing";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D0AFE3371A00282000C6048F /* Static Dependencies */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
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 */,
|
||||
D0AFE3411A00285000C6048F /* MTLReflection.m */,
|
||||
D0AFE33A1A00282C00C6048F /* MTLValueTransformer.m */,
|
||||
D09C66421A0055E6007D7ED0 /* NSArray+MTLManipulationAdditions.m */,
|
||||
D09C66281A00520B007D7ED0 /* NSArray+RACSequenceAdditions.m */,
|
||||
D09C66431A0055E6007D7ED0 /* NSDictionary+MTLManipulationAdditions.m */,
|
||||
D09C663E1A005433007D7ED0 /* NSEnumerator+RACSequenceAdditions.m */,
|
||||
D09C66441A0055E6007D7ED0 /* NSError+MTLModelException.m */,
|
||||
D09C664A1A0055F3007D7ED0 /* NSValueTransformer+MTLInversionAdditions.m */,
|
||||
D09C66451A0055E6007D7ED0 /* NSObject+MTLComparisonAdditions.m */,
|
||||
D09C66361A00537A007D7ED0 /* NSObject+RACDeallocating.m */,
|
||||
D09C66371A00537A007D7ED0 /* NSObject+RACDescription.m */,
|
||||
D09C662A1A005226007D7ED0 /* NSObject+RACKVOWrapper.m */,
|
||||
D09C662B1A005226007D7ED0 /* NSObject+RACPropertySubscribing.m */,
|
||||
D09C663C1A0053C6007D7ED0 /* NSString+RACKeyPathUtilities.m */,
|
||||
D0AFE3421A00285000C6048F /* NSValueTransformer+MTLPredefinedTransformerAdditions.m */,
|
||||
D0AFE3871A0028EC00C6048F /* RACArraySequence.m */,
|
||||
D0AFE34F1A0028A400C6048F /* RACBlockTrampoline.m */,
|
||||
D0AFE3451A00287100C6048F /* RACCommand.m */,
|
||||
D0AFE3501A0028A400C6048F /* RACCompoundDisposable.m */,
|
||||
D0AFE37B1A0028B000C6048F /* RACCompoundDisposableProvider.d */,
|
||||
D0AFE3461A00287100C6048F /* RACDisposable.m */,
|
||||
D0AFE3881A0028EC00C6048F /* RACDynamicSequence.m */,
|
||||
D0AFE3511A0028A400C6048F /* RACDynamicSignal.m */,
|
||||
D0AFE3891A0028EC00C6048F /* RACEagerSequence.m */,
|
||||
D0AFE3521A0028A400C6048F /* RACEmptySequence.m */,
|
||||
D0AFE3531A0028A400C6048F /* RACEmptySignal.m */,
|
||||
D0AFE3541A0028A400C6048F /* RACErrorSignal.m */,
|
||||
D0AFE3551A0028A400C6048F /* RACEvent.m */,
|
||||
D0AFE3561A0028A400C6048F /* RACGroupedSignal.m */,
|
||||
D0AFE3571A0028A400C6048F /* RACImmediateScheduler.m */,
|
||||
D06F7B0F1AD72DD30009A3BC /* RACKVOProxy.m */,
|
||||
D09C66341A00535B007D7ED0 /* RACKVOTrampoline.m */,
|
||||
D0AFE3581A0028A400C6048F /* RACMulticastConnection.m */,
|
||||
D09C663A1A00538D007D7ED0 /* RACObjCRuntime.m */,
|
||||
D0AFE37D1A0028CC00C6048F /* RACPassthroughSubscriber.m */,
|
||||
D0AFE37E1A0028CC00C6048F /* RACQueueScheduler.m */,
|
||||
D0AFE3591A0028A400C6048F /* RACReplaySubject.m */,
|
||||
D0AFE35A1A0028A400C6048F /* RACReturnSignal.m */,
|
||||
D0AFE3471A00287100C6048F /* RACScheduler.m */,
|
||||
D0AFE35B1A0028A400C6048F /* RACScopedDisposable.m */,
|
||||
D0AFE37F1A0028CC00C6048F /* RACSequence.m */,
|
||||
D0AFE35C1A0028A400C6048F /* RACSerialDisposable.m */,
|
||||
D0AFE3481A00287100C6048F /* RACSignal.m */,
|
||||
D0AFE3491A00287100C6048F /* RACSignal+Operations.m */,
|
||||
D0AFE3851A0028D500C6048F /* RACSignalProvider.d */,
|
||||
D0AFE35D1A0028A400C6048F /* RACSignalSequence.m */,
|
||||
D0AFE35E1A0028A400C6048F /* RACStream.m */,
|
||||
D0AFE35F1A0028A400C6048F /* RACSubject.m */,
|
||||
D0AFE3601A0028A400C6048F /* RACSubscriber.m */,
|
||||
D0AFE3611A0028A400C6048F /* RACSubscriptionScheduler.m */,
|
||||
D0AFE3621A0028A400C6048F /* RACTargetQueueScheduler.m */,
|
||||
D0AFE3631A0028A400C6048F /* RACTuple.m */,
|
||||
D0AFE3801A0028CC00C6048F /* RACTupleSequence.m */,
|
||||
D0AFE38A1A0028EC00C6048F /* RACUnarySequence.m */,
|
||||
D0AFE3641A0028A400C6048F /* RACUnit.m */,
|
||||
);
|
||||
name = "Static Dependencies";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D0C22BCD179CC00E00158214 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -612,13 +785,10 @@
|
||||
D0C22BD9179CC00E00158214 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BE31BE9F196B74A900376A76 /* libSpecta-OSX.a */,
|
||||
D0AFE3941A0029A700C6048F /* Nimble.framework */,
|
||||
D0AFE3921A00297500C6048F /* Quick.framework */,
|
||||
D4C4909A18E46DFE00786EFE /* ReactiveCocoa.framework */,
|
||||
D4C4909818E46DE900786EFE /* Mantle.framework */,
|
||||
D4C490A218E46E8800786EFE /* libReactiveCocoa-Mac.a */,
|
||||
D4C490A018E46E8200786EFE /* libMantle-Mac.a */,
|
||||
D4ACA4F518DB9CCB00EBD899 /* libExpecta.a */,
|
||||
D4ACA4F718DB9CCE00EBD899 /* libSpecta.a */,
|
||||
D4ACA50018DB9F3F00EBD899 /* OHHTTPStubs.framework */,
|
||||
D097B9BC17BB4777006C3FEB /* IOKit.framework */,
|
||||
D014ABB917B97403007D79D0 /* ServiceManagement.framework */,
|
||||
@@ -627,7 +797,6 @@
|
||||
F6EB217F179D0E4D001108CF /* Security.framework */,
|
||||
F6EB2161179CFD93001108CF /* SystemConfiguration.framework */,
|
||||
F60CA7EA179FC4F60069F69A /* Foundation.framework */,
|
||||
D0366C1C17B18FEE0086ED44 /* XCTest.framework */,
|
||||
D0366BFF17B18FEE0086ED44 /* Other Frameworks */,
|
||||
);
|
||||
name = Frameworks;
|
||||
@@ -648,8 +817,6 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D0C22BE2179CC00E00158214 /* Squirrel-Info.plist */,
|
||||
D0C22BE3179CC00E00158214 /* InfoPlist.strings */,
|
||||
D0C22BE6179CC00E00158214 /* Squirrel-Prefix.pch */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
@@ -666,13 +833,14 @@
|
||||
D0C22BF7179CC00E00158214 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D0EDBEDB17B0DB3E0058BC3C /* QuickSpec+SQRLFixtures.h */,
|
||||
D0EDBEDC17B0DB3E0058BC3C /* QuickSpec+SQRLFixtures.m */,
|
||||
D0AFE38F1A00294100C6048F /* SwiftSpec.swift */,
|
||||
D049059E180558B7004E683E /* SQRLTestUpdate.h */,
|
||||
D049059F180558B7004E683E /* SQRLTestUpdate.m */,
|
||||
D000219617BAD34D0050109A /* TestApplication.app.zip */,
|
||||
D09D244917B59AB30001FAF8 /* TestApplication 2.1.app */,
|
||||
D0C22BF8179CC00E00158214 /* SquirrelTests-Info.plist */,
|
||||
D0C22BF9179CC00E00158214 /* InfoPlist.strings */,
|
||||
D0C22C51179CC1A200158214 /* SquirrelTests-Prefix.pch */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
@@ -686,7 +854,7 @@
|
||||
D0C22C1C179CC02E00158214 /* README.md */,
|
||||
);
|
||||
name = Configuration;
|
||||
path = External/ReactiveCocoa/external/xcconfigs;
|
||||
path = Carthage/Checkouts/xcconfigs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D0C22C08179CC02E00158214 /* Base */ = {
|
||||
@@ -714,6 +882,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D0C22C10179CC02E00158214 /* Application.xcconfig */,
|
||||
D0AFE3351A00236E00C6048F /* Framework.xcconfig */,
|
||||
D0C22C11179CC02E00158214 /* StaticLibrary.xcconfig */,
|
||||
);
|
||||
path = Targets;
|
||||
@@ -724,6 +893,7 @@
|
||||
children = (
|
||||
D0C22C13179CC02E00158214 /* iOS-Application.xcconfig */,
|
||||
D0C22C14179CC02E00158214 /* iOS-Base.xcconfig */,
|
||||
D0AFE3361A00237400C6048F /* iOS-Framework.xcconfig */,
|
||||
D0C22C15179CC02E00158214 /* iOS-StaticLibrary.xcconfig */,
|
||||
);
|
||||
path = iOS;
|
||||
@@ -756,15 +926,10 @@
|
||||
children = (
|
||||
D00F5B8D17E82DE6009A4818 /* NSProcessInfoExtensionsSpec.m */,
|
||||
D0EDBEE017B0E3650058BC3C /* SQRLCodeSignatureSpec.m */,
|
||||
53710D7317D8F59700A992DE /* SQRLDeepCodesignSpec.m */,
|
||||
D049059A180554BA004E683E /* SQRLDirectoryManagerSpec.m */,
|
||||
D09D244017B595470001FAF8 /* SQRLInstallerSpec.m */,
|
||||
D049059C18055671004E683E /* SQRLShipItRequestSpec.m */,
|
||||
D06B58D018035B5A00656D97 /* SQRLTerminationListenerSpec.m */,
|
||||
D0EDBEDB17B0DB3E0058BC3C /* SQRLTestCase.h */,
|
||||
D0EDBEDC17B0DB3E0058BC3C /* SQRLTestCase.m */,
|
||||
BE312942196B999300F1A675 /* SQRLTestHelper.h */,
|
||||
BE312943196B999300F1A675 /* SQRLTestHelper.m */,
|
||||
D0C22C4F179CC18C00158214 /* SQRLUpdaterSpec.m */,
|
||||
5395C0E217E9D013001648E8 /* SQRLUpdateSpec.m */,
|
||||
D000219817BAD35C0050109A /* SQRLZipArchiverSpec.m */,
|
||||
@@ -908,7 +1073,8 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
CLASSPREFIX = SQRL;
|
||||
LastUpgradeCheck = 0510;
|
||||
LastSwiftUpdateCheck = 0710;
|
||||
LastUpgradeCheck = 0710;
|
||||
ORGANIZATIONNAME = GitHub;
|
||||
};
|
||||
buildConfigurationList = D0C22BD1179CC00E00158214 /* Build configuration list for PBXProject "Squirrel" */;
|
||||
@@ -949,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;
|
||||
@@ -958,7 +1123,6 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D0C22BE5179CC00E00158214 /* InfoPlist.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -966,11 +1130,9 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D0C22BFB179CC00E00158214 /* InfoPlist.strings in Resources */,
|
||||
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;
|
||||
};
|
||||
@@ -989,16 +1151,76 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D0AFE36F1A0028A400C6048F /* RACReplaySubject.m in Sources */,
|
||||
D0AFE3681A0028A400C6048F /* RACEmptySequence.m in Sources */,
|
||||
D09C663F1A005433007D7ED0 /* NSEnumerator+RACSequenceAdditions.m in Sources */,
|
||||
D09C66471A0055E6007D7ED0 /* NSDictionary+MTLManipulationAdditions.m in Sources */,
|
||||
D0AFE34C1A00287100C6048F /* RACScheduler.m in Sources */,
|
||||
D014AC1117B9789C007D79D0 /* SQRLInstaller.m in Sources */,
|
||||
D043F77217FF40C90012F996 /* SQRLTerminationListener.m in Sources */,
|
||||
D09C66481A0055E6007D7ED0 /* NSError+MTLModelException.m in Sources */,
|
||||
D0AFE3781A0028A400C6048F /* RACTargetQueueScheduler.m in Sources */,
|
||||
D0AFE3651A0028A400C6048F /* RACBlockTrampoline.m in Sources */,
|
||||
D0AFE3711A0028A400C6048F /* RACScopedDisposable.m in Sources */,
|
||||
D0AFE3661A0028A400C6048F /* RACCompoundDisposable.m in Sources */,
|
||||
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 */,
|
||||
D0AFE3741A0028A400C6048F /* RACStream.m in Sources */,
|
||||
D0AFE38D1A0028EC00C6048F /* RACEagerSequence.m in Sources */,
|
||||
D0AFE37A1A0028A400C6048F /* RACUnit.m in Sources */,
|
||||
D0AFE34D1A00287100C6048F /* RACSignal.m in Sources */,
|
||||
D09C663B1A00538D007D7ED0 /* RACObjCRuntime.m in Sources */,
|
||||
D014AC1917B979A8007D79D0 /* SQRLCodeSignature.m in Sources */,
|
||||
D0AFE34A1A00287100C6048F /* RACCommand.m in Sources */,
|
||||
D09C66381A00537A007D7ED0 /* NSObject+RACDeallocating.m in Sources */,
|
||||
5397A5D0187D92810014A477 /* SQRLShipItRequest.m in Sources */,
|
||||
D09C66461A0055E6007D7ED0 /* NSArray+MTLManipulationAdditions.m in Sources */,
|
||||
D06B58B618032B1500656D97 /* RACSignal+SQRLTransactionExtensions.m in Sources */,
|
||||
D0AFE33D1A00282C00C6048F /* MTLValueTransformer.m in Sources */,
|
||||
D0AFE3841A0028CC00C6048F /* RACTupleSequence.m in Sources */,
|
||||
5397A5EC187DA2570014A477 /* SQRLInstallerOwnedBundle.m in Sources */,
|
||||
D014AC1A17B979AA007D79D0 /* NSError+SQRLVerbosityExtensions.m in Sources */,
|
||||
D09C66411A005592007D7ED0 /* MTLModel+NSCoding.m in Sources */,
|
||||
D09C664B1A0055F3007D7ED0 /* NSValueTransformer+MTLInversionAdditions.m in Sources */,
|
||||
D0AFE36E1A0028A400C6048F /* RACMulticastConnection.m in Sources */,
|
||||
D0AFE34E1A00287100C6048F /* RACSignal+Operations.m in Sources */,
|
||||
D09C66491A0055E6007D7ED0 /* NSObject+MTLComparisonAdditions.m in Sources */,
|
||||
D0AFE38C1A0028EC00C6048F /* RACDynamicSequence.m in Sources */,
|
||||
D09C662C1A005226007D7ED0 /* NSObject+RACKVOWrapper.m in Sources */,
|
||||
D0AFE3821A0028CC00C6048F /* RACQueueScheduler.m in Sources */,
|
||||
D0AFE3771A0028A400C6048F /* RACSubscriptionScheduler.m in Sources */,
|
||||
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 */,
|
||||
D0AFE36A1A0028A400C6048F /* RACErrorSignal.m in Sources */,
|
||||
D0AFE3791A0028A400C6048F /* RACTuple.m in Sources */,
|
||||
D0AFE3811A0028CC00C6048F /* RACPassthroughSubscriber.m in Sources */,
|
||||
D0AFE3721A0028A400C6048F /* RACSerialDisposable.m in Sources */,
|
||||
D0964B3E17F2E20B00D88BF7 /* NSBundle+SQRLVersionExtensions.m in Sources */,
|
||||
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 */,
|
||||
D0AFE3831A0028CC00C6048F /* RACSequence.m in Sources */,
|
||||
D0AFE3671A0028A400C6048F /* RACDynamicSignal.m in Sources */,
|
||||
D0AFE3761A0028A400C6048F /* RACSubscriber.m in Sources */,
|
||||
D0AFE33C1A00282C00C6048F /* MTLModel.m in Sources */,
|
||||
D09C66291A00520B007D7ED0 /* NSArray+RACSequenceAdditions.m in Sources */,
|
||||
D09C663D1A0053C6007D7ED0 /* NSString+RACKeyPathUtilities.m in Sources */,
|
||||
D0AFE3701A0028A400C6048F /* RACReturnSignal.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -1042,15 +1264,14 @@
|
||||
D043F77E17FF43640012F996 /* SQRLTerminationListener.m in Sources */,
|
||||
D09D244117B595470001FAF8 /* SQRLInstallerSpec.m in Sources */,
|
||||
D0C22C50179CC18C00158214 /* SQRLUpdaterSpec.m in Sources */,
|
||||
D0EDBEDD17B0DB3E0058BC3C /* SQRLTestCase.m in Sources */,
|
||||
D0EDBEDD17B0DB3E0058BC3C /* QuickSpec+SQRLFixtures.m in Sources */,
|
||||
D0AFE3901A00294100C6048F /* SwiftSpec.swift in Sources */,
|
||||
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 */,
|
||||
BE312944196B999300F1A675 /* SQRLTestHelper.m in Sources */,
|
||||
D061E40217FD580D00CC134A /* SQRLInstaller.m in Sources */,
|
||||
D04905A0180558B7004E683E /* SQRLTestUpdate.m in Sources */,
|
||||
D049059D18055671004E683E /* SQRLShipItRequestSpec.m in Sources */,
|
||||
@@ -1112,22 +1333,6 @@
|
||||
name = Credits.rtf;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D0C22BE3179CC00E00158214 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
D0C22BE4179CC00E00158214 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D0C22BF9179CC00E00158214 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
D0C22BFA179CC00E00158214 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
@@ -1138,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;
|
||||
};
|
||||
@@ -1150,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;
|
||||
};
|
||||
@@ -1162,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;
|
||||
};
|
||||
@@ -1174,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;
|
||||
};
|
||||
@@ -1183,11 +1392,16 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C17179CC02E00158214 /* Mac-Application.xcconfig */;
|
||||
buildSettings = {
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
"mtl_copyPropertyAttributes=rac_copyPropertyAttributes",
|
||||
"mtl_propertyAttributes=rac_propertyAttributes",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"\"$(BUILT_PRODUCTS_DIR)/include/\"",
|
||||
"\"$(OBJROOT)/UninstalledProducts/include/\"",
|
||||
"$(inherited)",
|
||||
Carthage/Checkouts/Mantle,
|
||||
"Carthage/Checkouts/ReactiveCocoa/**",
|
||||
);
|
||||
OTHER_LDFLAGS = "-all_load";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
@@ -1197,11 +1411,16 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C17179CC02E00158214 /* Mac-Application.xcconfig */;
|
||||
buildSettings = {
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
"mtl_copyPropertyAttributes=rac_copyPropertyAttributes",
|
||||
"mtl_propertyAttributes=rac_propertyAttributes",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"\"$(BUILT_PRODUCTS_DIR)/include/\"",
|
||||
"\"$(OBJROOT)/UninstalledProducts/include/\"",
|
||||
"$(inherited)",
|
||||
Carthage/Checkouts/Mantle,
|
||||
"Carthage/Checkouts/ReactiveCocoa/**",
|
||||
);
|
||||
OTHER_LDFLAGS = "-all_load";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
@@ -1211,11 +1430,16 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C17179CC02E00158214 /* Mac-Application.xcconfig */;
|
||||
buildSettings = {
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
"mtl_copyPropertyAttributes=rac_copyPropertyAttributes",
|
||||
"mtl_propertyAttributes=rac_propertyAttributes",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"\"$(BUILT_PRODUCTS_DIR)/include/\"",
|
||||
"\"$(OBJROOT)/UninstalledProducts/include/\"",
|
||||
"$(inherited)",
|
||||
Carthage/Checkouts/Mantle,
|
||||
"Carthage/Checkouts/ReactiveCocoa/**",
|
||||
);
|
||||
OTHER_LDFLAGS = "-all_load";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
@@ -1225,11 +1449,16 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C17179CC02E00158214 /* Mac-Application.xcconfig */;
|
||||
buildSettings = {
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
"mtl_copyPropertyAttributes=rac_copyPropertyAttributes",
|
||||
"mtl_propertyAttributes=rac_propertyAttributes",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"\"$(BUILT_PRODUCTS_DIR)/include/\"",
|
||||
"\"$(OBJROOT)/UninstalledProducts/include/\"",
|
||||
"$(inherited)",
|
||||
Carthage/Checkouts/Mantle,
|
||||
"Carthage/Checkouts/ReactiveCocoa/**",
|
||||
);
|
||||
OTHER_LDFLAGS = "-all_load";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
@@ -1241,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;
|
||||
@@ -1257,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;
|
||||
@@ -1273,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;
|
||||
@@ -1289,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;
|
||||
@@ -1303,11 +1532,10 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C0B179CC02E00158214 /* Debug.xcconfig */;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_PREFIX_HEADER = "Squirrel/Squirrel-Prefix.pch";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
@@ -1316,12 +1544,8 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C0D179CC02E00158214 /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_PREFIX_HEADER = "Squirrel/Squirrel-Prefix.pch";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "NDEBUG=1";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
@@ -1330,11 +1554,16 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C1A179CC02E00158214 /* Mac-Framework.xcconfig */;
|
||||
buildSettings = {
|
||||
APPLICATION_EXTENSION_API_ONLY = NO;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/extobjc,
|
||||
);
|
||||
INFOPLIST_FILE = "Squirrel/Squirrel-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.${PRODUCT_NAME:rfc1034identifier}";
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
name = Debug;
|
||||
@@ -1343,11 +1572,16 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C1A179CC02E00158214 /* Mac-Framework.xcconfig */;
|
||||
buildSettings = {
|
||||
APPLICATION_EXTENSION_API_ONLY = NO;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/extobjc,
|
||||
);
|
||||
INFOPLIST_FILE = "Squirrel/Squirrel-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.${PRODUCT_NAME:rfc1034identifier}";
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
name = Release;
|
||||
@@ -1360,13 +1594,13 @@
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_PREFIX_HEADER = "SquirrelTests/SquirrelTests-Prefix.pch";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
External/ReactiveCocoa/external/specta/src,
|
||||
"External/ReactiveCocoa/external/expecta/src/**",
|
||||
"$(inherited)",
|
||||
Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/extobjc,
|
||||
);
|
||||
INFOPLIST_FILE = "SquirrelTests/SquirrelTests-Info.plist";
|
||||
OTHER_LDFLAGS = "-all_load";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
@@ -1379,13 +1613,13 @@
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_PREFIX_HEADER = "SquirrelTests/SquirrelTests-Prefix.pch";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
External/ReactiveCocoa/external/specta/src,
|
||||
"External/ReactiveCocoa/external/expecta/src/**",
|
||||
"$(inherited)",
|
||||
Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/extobjc,
|
||||
);
|
||||
INFOPLIST_FILE = "SquirrelTests/SquirrelTests-Info.plist";
|
||||
OTHER_LDFLAGS = "-all_load";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
@@ -1394,12 +1628,8 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C0C179CC02E00158214 /* Profile.xcconfig */;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_PREFIX_HEADER = "Squirrel/Squirrel-Prefix.pch";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "NDEBUG=1";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Profile;
|
||||
@@ -1408,11 +1638,16 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C1A179CC02E00158214 /* Mac-Framework.xcconfig */;
|
||||
buildSettings = {
|
||||
APPLICATION_EXTENSION_API_ONLY = NO;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/extobjc,
|
||||
);
|
||||
INFOPLIST_FILE = "Squirrel/Squirrel-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.${PRODUCT_NAME:rfc1034identifier}";
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
name = Profile;
|
||||
@@ -1425,13 +1660,13 @@
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_PREFIX_HEADER = "SquirrelTests/SquirrelTests-Prefix.pch";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
External/ReactiveCocoa/external/specta/src,
|
||||
"External/ReactiveCocoa/external/expecta/src/**",
|
||||
"$(inherited)",
|
||||
Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/extobjc,
|
||||
);
|
||||
INFOPLIST_FILE = "SquirrelTests/SquirrelTests-Info.plist";
|
||||
OTHER_LDFLAGS = "-all_load";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Profile;
|
||||
@@ -1440,11 +1675,8 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C0E179CC02E00158214 /* Test.xcconfig */;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_PREFIX_HEADER = "Squirrel/Squirrel-Prefix.pch";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Test;
|
||||
@@ -1453,11 +1685,16 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D0C22C1A179CC02E00158214 /* Mac-Framework.xcconfig */;
|
||||
buildSettings = {
|
||||
APPLICATION_EXTENSION_API_ONLY = NO;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/extobjc,
|
||||
);
|
||||
INFOPLIST_FILE = "Squirrel/Squirrel-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.${PRODUCT_NAME:rfc1034identifier}";
|
||||
WRAPPER_EXTENSION = framework;
|
||||
};
|
||||
name = Test;
|
||||
@@ -1470,13 +1707,13 @@
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_PREFIX_HEADER = "SquirrelTests/SquirrelTests-Prefix.pch";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
External/ReactiveCocoa/external/specta/src,
|
||||
"External/ReactiveCocoa/external/expecta/src/**",
|
||||
"$(inherited)",
|
||||
Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa/extobjc,
|
||||
);
|
||||
INFOPLIST_FILE = "SquirrelTests/SquirrelTests-Info.plist";
|
||||
OTHER_LDFLAGS = "-all_load";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.github.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Test;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0510"
|
||||
version = "1.3">
|
||||
LastUpgradeVersion = "0710"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
@@ -22,10 +22,10 @@
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForRunning = "NO"
|
||||
buildForProfiling = "NO"
|
||||
buildForArchiving = "NO"
|
||||
buildForAnalyzing = "YES">
|
||||
buildForAnalyzing = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D0C22BEE179CC00E00158214"
|
||||
@@ -37,10 +37,10 @@
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Test">
|
||||
shouldUseLaunchSchemeArgsEnv = "NO">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
@@ -53,16 +53,45 @@
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D0C22BD6179CC00E00158214"
|
||||
BuildableName = "Squirrel.framework"
|
||||
BlueprintName = "Squirrel"
|
||||
ReferencedContainer = "container:Squirrel.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<EnvironmentVariables>
|
||||
<EnvironmentVariable
|
||||
key = "FORCE_APP_IDENTIFIER"
|
||||
value = "com.github.Squirrel.SquirrelTests"
|
||||
isEnabled = "YES">
|
||||
</EnvironmentVariable>
|
||||
</EnvironmentVariables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
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
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D0C22BD6179CC00E00158214"
|
||||
BuildableName = "Squirrel.framework"
|
||||
BlueprintName = "Squirrel"
|
||||
ReferencedContainer = "container:Squirrel.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<EnvironmentVariables>
|
||||
<EnvironmentVariable
|
||||
key = "SQRLUpdateFromURL"
|
||||
@@ -74,11 +103,20 @@
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Profile"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Profile"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D0C22BD6179CC00E00158214"
|
||||
BuildableName = "Squirrel.framework"
|
||||
BlueprintName = "Squirrel"
|
||||
ReferencedContainer = "container:Squirrel.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0510"
|
||||
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,17 +38,21 @@
|
||||
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>
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D08D4E0B17B451500012B22D"
|
||||
@@ -61,12 +65,13 @@
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable>
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D08D4E0B17B451500012B22D"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0510"
|
||||
LastUpgradeVersion = "0710"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -23,30 +23,42 @@
|
||||
</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
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D014AC0017B97885007D79D0"
|
||||
BuildableName = "ShipIt"
|
||||
BlueprintName = "ShipIt"
|
||||
ReferencedContainer = "container:Squirrel.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
|
||||
+8
-8
@@ -5,18 +5,18 @@
|
||||
location = "group:Squirrel.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:External/Mantle/Mantle.xcodeproj">
|
||||
location = "group:Carthage/Checkouts/Mantle/Mantle.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:External/ReactiveCocoa/ReactiveCocoaFramework/ReactiveCocoa.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:External/ReactiveCocoa/external/specta/Specta.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:External/ReactiveCocoa/external/expecta/Expecta.xcodeproj">
|
||||
location = "group:Carthage/Checkouts/ReactiveCocoa/ReactiveCocoa.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:External/OHHTTPStubs/OHHTTPStubs/OHHTTPStubs.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Carthage/Checkouts/Quick/Quick.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Carthage/Checkouts/Nimble/Nimble.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
||||
@@ -14,4 +14,7 @@
|
||||
// Info.plist, or nil if the key is not present.
|
||||
@property (nonatomic, copy, readonly) NSString *sqrl_bundleVersion;
|
||||
|
||||
/// The value of the `kCFBundleExecutableKey` key.
|
||||
@property (nonatomic, copy, readonly) NSString *sqrl_executableName;
|
||||
|
||||
@end
|
||||
|
||||
@@ -14,4 +14,8 @@
|
||||
return [self objectForInfoDictionaryKey:(id)kCFBundleVersionKey];
|
||||
}
|
||||
|
||||
- (NSString *)sqrl_executableName {
|
||||
return [self objectForInfoDictionaryKey:(id)kCFBundleExecutableKey];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
#import <ReactiveCocoa/RACSignal.h>
|
||||
|
||||
@interface RACSignal (SQRLTransactionExtensions)
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
//
|
||||
|
||||
#import "RACSignal+SQRLTransactionExtensions.h"
|
||||
|
||||
#import <ReactiveCocoa/RACDisposable.h>
|
||||
#import <IOKit/pwr_mgt/IOPMLib.h>
|
||||
|
||||
// How long before power assertions time out.
|
||||
|
||||
@@ -7,8 +7,11 @@
|
||||
//
|
||||
|
||||
#import "SQRLCodeSignature.h"
|
||||
#import <ReactiveCocoa/EXTScope.h>
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
|
||||
#import "EXTKeyPathCoding.h"
|
||||
#import "EXTScope.h"
|
||||
#import <ReactiveCocoa/RACSignal+Operations.h>
|
||||
#import <ReactiveCocoa/RACSubscriber.h>
|
||||
#import <Security/Security.h>
|
||||
|
||||
NSString * const SQRLCodeSignatureErrorDomain = @"SQRLCodeSignatureErrorDomain";
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@class RACSignal;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
//
|
||||
|
||||
#import "SQRLDirectoryManager.h"
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
|
||||
#import <ReactiveCocoa/RACSignal+Operations.h>
|
||||
|
||||
@implementation SQRLDirectoryManager
|
||||
|
||||
@@ -23,7 +24,7 @@
|
||||
// Should only fallback to when running under otest, where
|
||||
// NSBundle.mainBundle doesn't return useful data.
|
||||
if (identifier == nil) {
|
||||
identifier = NSRunningApplication.currentApplication.localizedName;
|
||||
identifier = NSProcessInfo.processInfo.environment[@"FORCE_APP_IDENTIFIER"];
|
||||
}
|
||||
|
||||
NSAssert(identifier != nil, @"Could not automatically determine the current application's identifier");
|
||||
@@ -46,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];
|
||||
}
|
||||
@@ -62,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
|
||||
|
||||
+83
-22
@@ -7,6 +7,17 @@
|
||||
//
|
||||
|
||||
#import "SQRLInstaller.h"
|
||||
|
||||
#import <libkern/OSAtomic.h>
|
||||
#import "EXTScope.h"
|
||||
#import <ReactiveCocoa/NSEnumerator+RACSequenceAdditions.h>
|
||||
#import <ReactiveCocoa/NSObject+RACPropertySubscribing.h>
|
||||
#import <ReactiveCocoa/RACCommand.h>
|
||||
#import <ReactiveCocoa/RACSequence.h>
|
||||
#import <ReactiveCocoa/RACSignal+Operations.h>
|
||||
#import <ReactiveCocoa/RACSubscriber.h>
|
||||
#import <sys/xattr.h>
|
||||
|
||||
#import "NSBundle+SQRLVersionExtensions.h"
|
||||
#import "NSError+SQRLVerbosityExtensions.h"
|
||||
#import "RACSignal+SQRLTransactionExtensions.h"
|
||||
@@ -14,10 +25,6 @@
|
||||
#import "SQRLDirectoryManager.h"
|
||||
#import "SQRLShipItRequest.h"
|
||||
#import "SQRLTerminationListener.h"
|
||||
#import <libkern/OSAtomic.h>
|
||||
#import <ReactiveCocoa/EXTScope.h>
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
#import <sys/xattr.h>
|
||||
#import "SQRLInstallerOwnedBundle.h"
|
||||
|
||||
NSString * const SQRLInstallerErrorDomain = @"SQRLInstallerErrorDomain";
|
||||
@@ -165,7 +172,7 @@ NSString * const SQRLInstallerOwnedBundleKey = @"SQRLInstallerOwnedBundle";
|
||||
|
||||
return [self abortInstall];
|
||||
}];
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -255,27 +262,49 @@ NSString * const SQRLInstallerOwnedBundleKey = @"SQRLInstallerOwnedBundle";
|
||||
setNameWithFormat:@"%@ -acquireTargetBundleURLForRequest: %@", self, request];
|
||||
}
|
||||
|
||||
- (RACSignal *)renameIfNeeded:(SQRLShipItRequest *)request updateBundleURL:(NSURL *)updateBundleURL {
|
||||
if (!request.useUpdateBundleName) return [RACSignal return:request];
|
||||
|
||||
return [[self
|
||||
renamedTargetIfNeededWithTargetURL:request.targetBundleURL sourceURL:updateBundleURL]
|
||||
flattenMap:^(NSURL *newTargetURL) {
|
||||
if ([newTargetURL isEqual:request.targetBundleURL]) return [RACSignal return:request];
|
||||
|
||||
SQRLShipItRequest *updatedRequest = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:request.updateBundleURL targetBundleURL:newTargetURL bundleIdentifier:request.bundleIdentifier launchAfterInstallation:request.launchAfterInstallation useUpdateBundleName:request.useUpdateBundleName];
|
||||
return [[self
|
||||
installItemToURL:newTargetURL fromURL:request.targetBundleURL]
|
||||
concat:[RACSignal return:updatedRequest]];
|
||||
}];
|
||||
}
|
||||
|
||||
- (RACSignal *)installRequest:(SQRLShipItRequest *)request {
|
||||
NSParameterAssert(request != nil);
|
||||
|
||||
return [[[[self
|
||||
prepareAndValidateUpdateBundleURLForRequest:request]
|
||||
flattenMap:^(NSURL *updateBundleURL) {
|
||||
return [[[[[[[self
|
||||
acquireTargetBundleURLForRequest:request]
|
||||
concat:[self installItemToURL:request.targetBundleURL fromURL:updateBundleURL]]
|
||||
concat:[RACSignal return:request.updateBundleURL]]
|
||||
concat:[RACSignal return:updateBundleURL]]
|
||||
concat:[RACSignal defer:^{
|
||||
return [RACSignal return:self.ownedBundle.temporaryURL];
|
||||
}]]
|
||||
flattenMap:^(NSURL *location) {
|
||||
return [[[self
|
||||
deleteOwnedBundleAtURL:location]
|
||||
doError:^(NSError *error) {
|
||||
NSLog(@"Couldn't remove owned bundle at location %@, error %@", location, error.sqrl_verboseDescription);
|
||||
return [[[[self
|
||||
renameIfNeeded:request updateBundleURL:updateBundleURL]
|
||||
flattenMap:^(SQRLShipItRequest *request) {
|
||||
return [[self acquireTargetBundleURLForRequest:request] concat:[RACSignal return:request]];
|
||||
}]
|
||||
flattenMap:^(SQRLShipItRequest *request) {
|
||||
return [[[[[[self
|
||||
installItemToURL:request.targetBundleURL fromURL:updateBundleURL]
|
||||
concat:[RACSignal return:request.updateBundleURL]]
|
||||
concat:[RACSignal return:updateBundleURL]]
|
||||
concat:[RACSignal defer:^{
|
||||
return [RACSignal return:self.ownedBundle.temporaryURL];
|
||||
}]]
|
||||
flattenMap:^(NSURL *location) {
|
||||
return [[[self
|
||||
deleteOwnedBundleAtURL:location]
|
||||
doError:^(NSError *error) {
|
||||
NSLog(@"Couldn't remove owned bundle at location %@, error %@", location, error.sqrl_verboseDescription);
|
||||
}]
|
||||
catchTo:[RACSignal empty]];
|
||||
}]
|
||||
catchTo:[RACSignal empty]];
|
||||
concat:[RACSignal return:request]];
|
||||
}]
|
||||
doCompleted:^{
|
||||
self.ownedBundle = nil;
|
||||
@@ -406,6 +435,36 @@ NSString * const SQRLInstallerOwnedBundleKey = @"SQRLInstallerOwnedBundle";
|
||||
|
||||
#pragma mark Installation
|
||||
|
||||
/// Check if the target should be renamed and provide the renamed URL.
|
||||
///
|
||||
/// targetURL - The URL for the target. Cannot be nil.
|
||||
/// sourceURL - The URL for the source. Cannot be nil.
|
||||
///
|
||||
/// Returns a signal which will send the URL for the renamed target. If a rename
|
||||
/// isn't needed then it will send `targetURL`.
|
||||
- (RACSignal *)renamedTargetIfNeededWithTargetURL:(NSURL *)targetURL sourceURL:(NSURL *)sourceURL {
|
||||
return [RACSignal defer:^{
|
||||
NSBundle *sourceBundle = [NSBundle bundleWithURL:sourceURL];
|
||||
NSString *targetExecutableName = targetURL.lastPathComponent.stringByDeletingPathExtension;
|
||||
NSString *sourceExecutableName = sourceBundle.sqrl_executableName;
|
||||
|
||||
// If they're already the same then we're good.
|
||||
if ([targetExecutableName isEqual:sourceExecutableName]) {
|
||||
return [RACSignal return:targetURL];
|
||||
}
|
||||
|
||||
NSString *newAppName = [sourceExecutableName stringByAppendingPathExtension:@"app"];
|
||||
NSURL *newTargetURL = [targetURL.URLByDeletingLastPathComponent URLByAppendingPathComponent:newAppName];
|
||||
|
||||
// If there's already something there then don't rename to it.
|
||||
if ([NSFileManager.defaultManager fileExistsAtPath:newTargetURL.path]) {
|
||||
return [RACSignal return:targetURL];
|
||||
}
|
||||
|
||||
return [RACSignal return:newTargetURL];
|
||||
}];
|
||||
}
|
||||
|
||||
- (RACSignal *)installItemToURL:(NSURL *)targetURL fromURL:(NSURL *)sourceURL {
|
||||
NSParameterAssert(targetURL != nil);
|
||||
NSParameterAssert(sourceURL != nil);
|
||||
@@ -418,7 +477,7 @@ NSString * const SQRLInstallerOwnedBundleKey = @"SQRLInstallerOwnedBundle";
|
||||
} else {
|
||||
int code = errno;
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
|
||||
|
||||
|
||||
const char *desc = strerror(code);
|
||||
if (desc != NULL) userInfo[NSLocalizedDescriptionKey] = @(desc);
|
||||
|
||||
@@ -470,7 +529,7 @@ NSString * const SQRLInstallerOwnedBundleKey = @"SQRLInstallerOwnedBundle";
|
||||
// file to begin with.
|
||||
if (code != ENOATTR) {
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
|
||||
|
||||
|
||||
const char *desc = strerror(code);
|
||||
if (desc != NULL) userInfo[NSLocalizedDescriptionKey] = @(desc);
|
||||
|
||||
@@ -526,7 +585,9 @@ NSString * const SQRLInstallerOwnedBundleKey = @"SQRLInstallerOwnedBundle";
|
||||
return NO;
|
||||
}];
|
||||
|
||||
return [enumerator.rac_sequence.signal subscribe:subscriber];
|
||||
return [[enumerator.rac_sequence.signal
|
||||
startWith:directoryURL]
|
||||
subscribe:subscriber];
|
||||
}]
|
||||
flattenMap:^(NSURL *itemURL) {
|
||||
return [[[self
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#import "SQRLInstallerOwnedBundle.h"
|
||||
|
||||
#import <ReactiveCocoa/EXTKeyPathCoding.h>
|
||||
#import "EXTKeyPathCoding.h"
|
||||
|
||||
@implementation SQRLInstallerOwnedBundle
|
||||
|
||||
|
||||
@@ -22,8 +22,7 @@ const NSInteger SQRLShipItLauncherErrorCouldNotStartService = 1;
|
||||
@implementation SQRLShipItLauncher
|
||||
|
||||
+ (NSString *)shipItJobLabel {
|
||||
NSString *currentAppIdentifier = NSBundle.mainBundle.bundleIdentifier ?: [NSString stringWithFormat:@"%@:%d", NSProcessInfo.processInfo.processName, NSProcessInfo.processInfo.processIdentifier];
|
||||
return [currentAppIdentifier stringByAppendingString:@".ShipIt"];
|
||||
return [SQRLDirectoryManager.currentApplicationManager.applicationIdentifier stringByAppendingString:@".ShipIt"];
|
||||
}
|
||||
|
||||
+ (RACSignal *)shipItJobDictionary {
|
||||
@@ -32,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");
|
||||
|
||||
@@ -58,13 +57,9 @@ 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;
|
||||
|
||||
#if DEBUG
|
||||
jobDict[@(LAUNCH_JOBKEY_DEBUG)] = @YES;
|
||||
#endif
|
||||
|
||||
return jobDict;
|
||||
}]
|
||||
setNameWithFormat:@"+shipItJobDictionary"];
|
||||
|
||||
@@ -73,10 +73,11 @@ extern NSString * const SQRLShipItRequestPropertyErrorKey;
|
||||
// installing. Can be nil.
|
||||
// launchAfterInstallation - Whether the updated application should be launched
|
||||
// after installation.
|
||||
// useUpdateBundleName - Should the target use the update bundle's name?
|
||||
//
|
||||
// Returns a request which can be written to disk for ShipIt to read and
|
||||
// perform.
|
||||
- (instancetype)initWithUpdateBundleURL:(NSURL *)updateBundleURL targetBundleURL:(NSURL *)targetBundleURL bundleIdentifier:(NSString *)bundleIdentifier launchAfterInstallation:(BOOL)launchAfterInstallation;
|
||||
- (instancetype)initWithUpdateBundleURL:(NSURL *)updateBundleURL targetBundleURL:(NSURL *)targetBundleURL bundleIdentifier:(NSString *)bundleIdentifier launchAfterInstallation:(BOOL)launchAfterInstallation useUpdateBundleName:(BOOL)useUpdateBundleName;
|
||||
|
||||
// The URL to the downloaded update's app bundle.
|
||||
@property (nonatomic, copy, readonly) NSURL *updateBundleURL;
|
||||
@@ -93,4 +94,7 @@ extern NSString * const SQRLShipItRequestPropertyErrorKey;
|
||||
// Whether to launch the application after an update is successfully installed.
|
||||
@property (nonatomic, assign, readonly) BOOL launchAfterInstallation;
|
||||
|
||||
// Whether the app should use the update bundle's name.
|
||||
@property (nonatomic, assign, readonly) BOOL useUpdateBundleName;
|
||||
|
||||
@end
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
|
||||
#import "SQRLShipItRequest.h"
|
||||
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
#import "EXTKeyPathCoding.h"
|
||||
#import <ReactiveCocoa/RACSignal+Operations.h>
|
||||
|
||||
NSString * const SQRLShipItRequestErrorDomain = @"SQRLShipItRequestErrorDomain";
|
||||
|
||||
@@ -46,12 +47,13 @@ NSString * const SQRLShipItRequestPropertyErrorKey = @"SQRLShipItRequestProperty
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithUpdateBundleURL:(NSURL *)updateBundleURL targetBundleURL:(NSURL *)targetBundleURL bundleIdentifier:(NSString *)bundleIdentifier launchAfterInstallation:(BOOL)launchAfterInstallation {
|
||||
- (instancetype)initWithUpdateBundleURL:(NSURL *)updateBundleURL targetBundleURL:(NSURL *)targetBundleURL bundleIdentifier:(NSString *)bundleIdentifier launchAfterInstallation:(BOOL)launchAfterInstallation useUpdateBundleName:(BOOL)useUpdateBundleName {
|
||||
return [self initWithDictionary:@{
|
||||
@keypath(self.updateBundleURL): updateBundleURL,
|
||||
@keypath(self.targetBundleURL): targetBundleURL,
|
||||
@keypath(self.bundleIdentifier): bundleIdentifier ?: NSNull.null,
|
||||
@keypath(self.launchAfterInstallation): @(launchAfterInstallation),
|
||||
@keypath(self.useUpdateBundleName): @(useUpdateBundleName),
|
||||
} error:NULL];
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@class RACSignal;
|
||||
|
||||
|
||||
@@ -7,7 +7,14 @@
|
||||
//
|
||||
|
||||
#import "SQRLTerminationListener.h"
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
|
||||
#import "EXTKeyPathCoding.h"
|
||||
#import <ReactiveCocoa/NSArray+RACSequenceAdditions.h>
|
||||
#import <ReactiveCocoa/RACDisposable.h>
|
||||
#import <ReactiveCocoa/RACScheduler.h>
|
||||
#import <ReactiveCocoa/RACSequence.h>
|
||||
#import <ReactiveCocoa/RACSignal+Operations.h>
|
||||
#import <ReactiveCocoa/RACSubscriber.h>
|
||||
|
||||
@interface SQRLTerminationListener ()
|
||||
|
||||
@@ -74,7 +81,6 @@
|
||||
dispatch_resume(source);
|
||||
return [RACDisposable disposableWithBlock:^{
|
||||
dispatch_source_cancel(source);
|
||||
dispatch_release(source);
|
||||
}];
|
||||
}]
|
||||
setNameWithFormat:@"%@ -waitForTerminationOfProcessIdentifier: %i", self, (int)processIdentifier];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
|
||||
// Represents the current state of the updater.
|
||||
//
|
||||
// SQRLUpdaterStateIdle - Doing absolutely diddly squat.
|
||||
|
||||
+158
-82
@@ -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;
|
||||
|
||||
@@ -341,36 +304,87 @@ static NSString * const SQRLUpdaterUniqueTemporaryDirectoryPrefix = @"update.";
|
||||
return [[[self
|
||||
uniqueTemporaryDirectoryForUpdate]
|
||||
flattenMap:^(NSURL *downloadDirectory) {
|
||||
void (^cleanUp)(void) = ^{
|
||||
NSError *error;
|
||||
if (![NSFileManager.defaultManager removeItemAtURL:downloadDirectory error:&error]) {
|
||||
NSLog(@"Error removing temporary download directory at %@: %@", downloadDirectory, error.sqrl_verboseDescription);
|
||||
}
|
||||
};
|
||||
|
||||
return [[[self
|
||||
downloadBundleForUpdate:update intoDirectory:downloadDirectory]
|
||||
flattenMap:^(NSBundle *updateBundle) {
|
||||
// If the bundle is nil it means our conditional GET told us
|
||||
// we already downloaded the update. So just clean up.
|
||||
if (updateBundle == nil) {
|
||||
cleanUp();
|
||||
return [RACSignal empty];
|
||||
}
|
||||
|
||||
return [self verifyAndPrepareUpdate:update fromBundle:updateBundle];
|
||||
}]
|
||||
doError:^(id _) {
|
||||
NSError *error = nil;
|
||||
if (![NSFileManager.defaultManager removeItemAtURL:downloadDirectory error:&error]) {
|
||||
NSLog(@"Error removing temporary download directory at %@: %@", downloadDirectory, error.sqrl_verboseDescription);
|
||||
}
|
||||
cleanUp();
|
||||
}];
|
||||
}]
|
||||
setNameWithFormat:@"%@ -downloadAndPrepareUpdate: %@", self, update];
|
||||
}
|
||||
|
||||
- (RACSignal *)unarchiveAndPrepareData:(NSData *)data withName:(NSString *)name intoDirectory:(NSURL *)downloadDirectory {
|
||||
return [[[[[RACSignal
|
||||
defer:^{
|
||||
NSURL *zipOutputURL = [downloadDirectory URLByAppendingPathComponent:name];
|
||||
NSError *error = nil;
|
||||
if ([data writeToURL:zipOutputURL options:NSDataWritingAtomic error:&error]) {
|
||||
return [RACSignal return:zipOutputURL];
|
||||
} else {
|
||||
return [RACSignal error:error];
|
||||
}
|
||||
}]
|
||||
doNext:^(NSURL *zipOutputURL) {
|
||||
NSLog(@"Download completed to: %@", zipOutputURL);
|
||||
}]
|
||||
flattenMap:^(NSURL *zipOutputURL) {
|
||||
return [[[[SQRLZipArchiver
|
||||
unzipArchiveAtURL:zipOutputURL intoDirectoryAtURL:downloadDirectory]
|
||||
ignoreValues]
|
||||
concat:[RACSignal return:zipOutputURL]]
|
||||
doCompleted:^{
|
||||
NSError *error = nil;
|
||||
if (![NSFileManager.defaultManager removeItemAtURL:zipOutputURL error:&error]) {
|
||||
NSLog(@"Error removing downloaded archive at %@: %@", zipOutputURL, error.sqrl_verboseDescription);
|
||||
}
|
||||
}];
|
||||
}]
|
||||
flattenMap:^(NSURL *zipOutputURL) {
|
||||
return [self updateBundleMatchingCurrentApplicationInDirectory:downloadDirectory];
|
||||
}]
|
||||
setNameWithFormat:@"%@ -unarchiveAndPrepareData:withName: %@ intoDirectory: %@", self, name, downloadDirectory];
|
||||
}
|
||||
|
||||
- (RACSignal *)downloadBundleForUpdate:(SQRLUpdate *)update intoDirectory:(NSURL *)downloadDirectory {
|
||||
NSParameterAssert(update != nil);
|
||||
NSParameterAssert(downloadDirectory != nil);
|
||||
|
||||
return [[[[[RACSignal
|
||||
return [[RACSignal
|
||||
defer:^{
|
||||
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
|
||||
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 return:nil];
|
||||
}
|
||||
|
||||
if (!(httpResponse.statusCode >= 200 && httpResponse.statusCode <= 299)) {
|
||||
NSDictionary *errorInfo = @{
|
||||
NSLocalizedDescriptionKey: NSLocalizedString(@"Update download failed", nil),
|
||||
@@ -380,37 +394,13 @@ 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];
|
||||
return [self unarchiveAndPrepareData:bodyData withName:zipDownloadURL.lastPathComponent intoDirectory:downloadDirectory];
|
||||
}]
|
||||
flatten]
|
||||
flattenMap:^(NSData *data) {
|
||||
NSURL *zipOutputURL = [downloadDirectory URLByAppendingPathComponent:zipDownloadURL.lastPathComponent];
|
||||
|
||||
NSError *error = nil;
|
||||
if ([data writeToURL:zipOutputURL options:NSDataWritingAtomic error:&error]) {
|
||||
return [RACSignal return:zipOutputURL];
|
||||
} else {
|
||||
return [RACSignal error:error];
|
||||
}
|
||||
}];
|
||||
}]
|
||||
doNext:^(NSURL *zipOutputURL) {
|
||||
NSLog(@"Download completed to: %@", zipOutputURL);
|
||||
}]
|
||||
flattenMap:^(NSURL *zipOutputURL) {
|
||||
return [[SQRLZipArchiver
|
||||
unzipArchiveAtURL:zipOutputURL intoDirectoryAtURL:downloadDirectory]
|
||||
doCompleted:^{
|
||||
NSError *error = nil;
|
||||
if (![NSFileManager.defaultManager removeItemAtURL:zipOutputURL error:&error]) {
|
||||
NSLog(@"Error removing downloaded archive at %@: %@", zipOutputURL, error.sqrl_verboseDescription);
|
||||
}
|
||||
}];
|
||||
}]
|
||||
then:^{
|
||||
return [self updateBundleMatchingCurrentApplicationInDirectory:downloadDirectory];
|
||||
flatten];
|
||||
}]
|
||||
setNameWithFormat:@"%@ -downloadBundleForUpdate: %@ intoDirectory: %@", self, update, downloadDirectory];
|
||||
}
|
||||
@@ -421,10 +411,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 +492,87 @@ 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:^{
|
||||
// If we already have updates downloaded we don't wanna prune them.
|
||||
if (self.state == SQRLUpdaterStateAwaitingRelaunch) return [RACSignal empty];
|
||||
|
||||
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 {
|
||||
@@ -528,7 +599,12 @@ static NSString * const SQRLUpdaterUniqueTemporaryDirectoryPrefix = @"update.";
|
||||
return [[[[RACSignal
|
||||
defer:^{
|
||||
NSRunningApplication *currentApplication = NSRunningApplication.currentApplication;
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:update.bundle.bundleURL targetBundleURL:currentApplication.bundleURL bundleIdentifier:currentApplication.bundleIdentifier launchAfterInstallation:NO];
|
||||
NSBundle *appBundle = [NSBundle bundleWithURL:currentApplication.bundleURL];
|
||||
// Only use the update bundle's name if the user hasn't renamed the
|
||||
// app themselves.
|
||||
BOOL useUpdateBundleName = [appBundle.sqrl_executableName isEqual:currentApplication.bundleURL.lastPathComponent.stringByDeletingPathExtension];
|
||||
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:update.bundle.bundleURL targetBundleURL:currentApplication.bundleURL bundleIdentifier:currentApplication.bundleIdentifier launchAfterInstallation:NO useUpdateBundleName:useUpdateBundleName];
|
||||
return [request writeUsingURL:self.shipItStateURL];
|
||||
}]
|
||||
then:^{
|
||||
@@ -542,7 +618,7 @@ static NSString * const SQRLUpdaterUniqueTemporaryDirectoryPrefix = @"update.";
|
||||
return [[[[[[[[SQRLShipItRequest
|
||||
readUsingURL:self.shipItStateURL]
|
||||
map:^(SQRLShipItRequest *request) {
|
||||
return [[SQRLShipItRequest alloc] initWithUpdateBundleURL:request.updateBundleURL targetBundleURL:request.targetBundleURL bundleIdentifier:request.bundleIdentifier launchAfterInstallation:YES];
|
||||
return [[SQRLShipItRequest alloc] initWithUpdateBundleURL:request.updateBundleURL targetBundleURL:request.targetBundleURL bundleIdentifier:request.bundleIdentifier launchAfterInstallation:YES useUpdateBundleName:request.useUpdateBundleName];
|
||||
}]
|
||||
flattenMap:^(SQRLShipItRequest *request) {
|
||||
return [[request
|
||||
|
||||
+12
-7
@@ -7,8 +7,12 @@
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <ReactiveCocoa/EXTScope.h>
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
|
||||
#import "EXTScope.h"
|
||||
#import <ReactiveCocoa/RACCommand.h>
|
||||
#import <ReactiveCocoa/RACSignal+Operations.h>
|
||||
#import <ReactiveCocoa/RACScheduler.h>
|
||||
|
||||
#import "NSError+SQRLVerbosityExtensions.h"
|
||||
#import "RACSignal+SQRLTransactionExtensions.h"
|
||||
#import "SQRLDirectoryManager.h"
|
||||
@@ -71,7 +75,7 @@ static void installRequest(RACSignal *readRequestSignal, SQRLDirectoryManager *d
|
||||
|
||||
RACSignal *action;
|
||||
if (attempt > SQRLShipItMaximumInstallationAttempts) {
|
||||
action = [[[installer.abortInstallationCommand
|
||||
action = [[[[installer.abortInstallationCommand
|
||||
execute:request]
|
||||
initially:^{
|
||||
NSLog(@"Too many attempts to install, aborting update");
|
||||
@@ -82,7 +86,8 @@ static void installRequest(RACSignal *readRequestSignal, SQRLDirectoryManager *d
|
||||
// Exit successfully so launchd doesn't restart us
|
||||
// again.
|
||||
return [RACSignal empty];
|
||||
}];
|
||||
}]
|
||||
concat:[RACSignal return:request]];
|
||||
} else {
|
||||
action = [[[[installer.installUpdateCommand
|
||||
execute:request]
|
||||
@@ -110,15 +115,15 @@ static void installRequest(RACSignal *readRequestSignal, SQRLDirectoryManager *d
|
||||
// Launch regardless of whether installation succeeds or fails.
|
||||
action = [[action
|
||||
deliverOn:RACScheduler.mainThreadScheduler]
|
||||
finally:^{
|
||||
NSURL *bundleURL = request.targetBundleURL;
|
||||
doNext:^(SQRLShipItRequest *finalRequest) {
|
||||
NSURL *bundleURL = finalRequest.targetBundleURL;
|
||||
if (bundleURL == nil) {
|
||||
NSLog(@"Missing target bundle URL, cannot launch application");
|
||||
return;
|
||||
}
|
||||
|
||||
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>
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
//
|
||||
// Prefix header for all source files of the 'Squirrel' target in the 'Squirrel' project
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
#endif
|
||||
@@ -6,6 +6,14 @@
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
//! Project version number for Squirrel.
|
||||
FOUNDATION_EXPORT double SquirrelVersionNumber;
|
||||
|
||||
//! Project version string for Squirrel.
|
||||
FOUNDATION_EXPORT const unsigned char SquirrelVersionString[];
|
||||
|
||||
#import <Squirrel/NSBundle+SQRLVersionExtensions.h>
|
||||
#import <Squirrel/NSProcessInfo+SQRLVersionExtensions.h>
|
||||
#import <Squirrel/SQRLDownloadedUpdate.h>
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
@@ -6,30 +6,35 @@
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
SpecBegin(NSProcessInfoExtensions)
|
||||
#import <Nimble/Nimble.h>
|
||||
#import <Quick/Quick.h>
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
#import <Squirrel/Squirrel.h>
|
||||
|
||||
QuickSpecBegin(NSProcessInfoExtensions)
|
||||
|
||||
describe(@"-sqrl_operatingSystemShortVersionString", ^{
|
||||
__block NSString *versionString;
|
||||
|
||||
beforeEach(^{
|
||||
versionString = NSProcessInfo.processInfo.sqrl_operatingSystemShortVersionString;
|
||||
expect(versionString).notTo.beNil();
|
||||
expect(versionString).notTo(beNil());
|
||||
});
|
||||
|
||||
it(@"should follow major.minor.patch format", ^{
|
||||
NSError *error = nil;
|
||||
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^[0-9]+(\\.[0-9]+)*$" options:0 error:&error];
|
||||
expect(regex).notTo.beNil();
|
||||
expect(error).to.beNil();
|
||||
expect(regex).notTo(beNil());
|
||||
expect(error).to(beNil());
|
||||
|
||||
NSRange fullRange = NSMakeRange(0, versionString.length);
|
||||
NSRange matchRange = [regex rangeOfFirstMatchInString:versionString options:0 range:fullRange];
|
||||
expect(NSEqualRanges(matchRange, fullRange)).to.beTruthy();
|
||||
expect(@(NSEqualRanges(matchRange, fullRange))).to(beTruthy());
|
||||
});
|
||||
|
||||
it(@"should be numerically comparable", ^{
|
||||
expect([@"10.6.9" compare:versionString options:NSNumericSearch]).to.equal(NSOrderedAscending);
|
||||
expect(@([@"10.6.9" compare:versionString options:NSNumericSearch])).to(equal(@(NSOrderedAscending)));
|
||||
});
|
||||
});
|
||||
|
||||
SpecEnd
|
||||
QuickSpecEnd
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
//
|
||||
// SQRLTestCase.h
|
||||
// QuickSpec+SQRLFixtures.h
|
||||
// Squirrel
|
||||
//
|
||||
// Created by Justin Spahr-Summers on 2013-08-06.
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Nimble/Nimble.h>
|
||||
#import <Quick/Quick.h>
|
||||
#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;
|
||||
|
||||
@@ -16,11 +24,15 @@ 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;
|
||||
|
||||
@interface SQRLTestCase : SPTXCTestCase
|
||||
@interface QuickSpec (SQRLFixtures)
|
||||
|
||||
// A URL to a temporary directory tests can use.
|
||||
//
|
||||
@@ -49,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
|
||||
@@ -1,20 +1,20 @@
|
||||
//
|
||||
// SQRLTestCase.m
|
||||
// QuickSpec+SQRLFixtures.m
|
||||
// Squirrel
|
||||
//
|
||||
// Created by Justin Spahr-Summers on 2013-08-06.
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SQRLTestCase.h"
|
||||
#import "QuickSpec+SQRLFixtures.h"
|
||||
|
||||
#import "SQRLCodeSignature.h"
|
||||
#import "SQRLDirectoryManager.h"
|
||||
#import "SQRLInstaller.h"
|
||||
#import "SQRLShipItLauncher.h"
|
||||
#import "SQRLShipItRequest.h"
|
||||
#import "SQRLTestHelper.h"
|
||||
#import <ServiceManagement/ServiceManagement.h>
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Warc-retain-cycles"
|
||||
@@ -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,40 +45,25 @@ static void SQRLSignalHandler(int sig) {
|
||||
abort();
|
||||
}
|
||||
|
||||
@interface SQRLTestCase ()
|
||||
static NSBundle *SQRLTestBundle(void) {
|
||||
return [NSBundle bundleWithIdentifier:@"com.github.SquirrelTests"];
|
||||
}
|
||||
|
||||
// An array of dispatch_block_t values, for performing cleanup after the current
|
||||
// example finishes.
|
||||
//
|
||||
// This array will be emptied between each example.
|
||||
@property (nonatomic, strong, readonly) NSMutableArray *exampleCleanupBlocks;
|
||||
static NSMutableArray *cleanupBlocks = nil;
|
||||
|
||||
// The URL to the temporary directory which contains `temporaryDirectoryURL` and
|
||||
// all copied test data.
|
||||
@property (nonatomic, copy, readonly) NSURL *baseTemporaryDirectoryURL;
|
||||
static NSURL *baseTemporaryDirectoryURL = nil;
|
||||
|
||||
// Returns an _unlaunched_ task that will follow log files at the given paths,
|
||||
// then pipe that output through this process.
|
||||
+ (NSTask *)tailTaskWithPaths:(RACSequence *)paths;
|
||||
QuickConfigurationBegin(Fixtures)
|
||||
|
||||
@end
|
||||
|
||||
@implementation SQRLTestCase
|
||||
|
||||
#pragma mark Properties
|
||||
|
||||
@synthesize baseTemporaryDirectoryURL = _baseTemporaryDirectoryURL;
|
||||
|
||||
#pragma mark Lifecycle
|
||||
|
||||
+ (void)load {
|
||||
+ (void)configure:(Configuration *)configuration {
|
||||
NSURL *appSupportURL = [NSFileManager.defaultManager URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:NULL];
|
||||
NSAssert(appSupportURL != nil, @"Could not find Application Support folder");
|
||||
|
||||
NSArray *folders = @[
|
||||
@"com.github.Squirrel.TestApplication.ShipIt",
|
||||
@"otest.ShipIt",
|
||||
@"otest-x86_64.ShipIt",
|
||||
@"com.github.Squirrel.SquirrelTests.ShipIt",
|
||||
];
|
||||
|
||||
RACSequence *URLs = [folders.rac_sequence flattenMap:^(NSString *folder) {
|
||||
@@ -87,79 +74,69 @@ static void SQRLSignalHandler(int sig) {
|
||||
].rac_sequence;
|
||||
}];
|
||||
|
||||
for (NSURL *URL in URLs) {
|
||||
[[NSData data] writeToURL:URL atomically:YES];
|
||||
}
|
||||
[configuration beforeSuite:^{
|
||||
signal(SIGILL, &SQRLSignalHandler);
|
||||
NSSetUncaughtExceptionHandler(&SQRLUncaughtExceptionHandler);
|
||||
|
||||
RACSequence *paths = [URLs map:^(NSURL *URL) {
|
||||
return URL.path;
|
||||
cleanupBlocks = [NSMutableArray array];
|
||||
|
||||
for (NSURL *URL in URLs) {
|
||||
[NSFileManager.defaultManager createDirectoryAtURL:URL.URLByDeletingLastPathComponent withIntermediateDirectories:YES attributes:nil error:NULL];
|
||||
if (![[NSData data] writeToURL:URL atomically:YES]) {
|
||||
NSLog(@"Could not touch log file at %@", URL);
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
NSTask *readShipIt = [self tailTaskWithPaths:paths];
|
||||
[readShipIt launch];
|
||||
// We want to run any enqueued cleanup blocks after _and before_ each spec,
|
||||
// in case beforeSuites (for example) use the fixtures.
|
||||
void (^runCleanupBlocks)(void) = ^{
|
||||
// Enumerate backwards, so later resources are cleaned up first.
|
||||
for (dispatch_block_t block in cleanupBlocks.reverseObjectEnumerator) {
|
||||
block();
|
||||
}
|
||||
|
||||
NSAssert([readShipIt isRunning], @"Could not start task %@", readShipIt);
|
||||
|
||||
atexit_b(^{
|
||||
[readShipIt terminate];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)setUp {
|
||||
[super setUp];
|
||||
|
||||
signal(SIGILL, &SQRLSignalHandler);
|
||||
NSSetUncaughtExceptionHandler(&SQRLUncaughtExceptionHandler);
|
||||
|
||||
Expecta.asynchronousTestTimeout = 3;
|
||||
}
|
||||
|
||||
- (void)tearDown {
|
||||
[super tearDown];
|
||||
|
||||
SQRLKillAllTestApplications();
|
||||
}
|
||||
|
||||
- (void)addCleanupBlock:(dispatch_block_t)block {
|
||||
[SQRLTestHelper addCleanupBlock:block];
|
||||
}
|
||||
|
||||
#pragma mark Logging
|
||||
|
||||
+ (NSTask *)tailTaskWithPaths:(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);
|
||||
[cleanupBlocks removeAllObjects];
|
||||
};
|
||||
|
||||
NSTask *task = [[NSTask alloc] init];
|
||||
task.launchPath = @"/usr/bin/tail";
|
||||
task.standardOutput = outputPipe;
|
||||
task.arguments = [[paths startWith:@"-f"] array];
|
||||
return task;
|
||||
[configuration beforeEach:^{
|
||||
runCleanupBlocks();
|
||||
}];
|
||||
|
||||
[configuration afterEach:^{
|
||||
runCleanupBlocks();
|
||||
SQRLKillAllTestApplications();
|
||||
}];
|
||||
}
|
||||
|
||||
QuickConfigurationEnd
|
||||
|
||||
@implementation QuickSpec (SQRLFixtures)
|
||||
|
||||
#pragma mark Lifecycle
|
||||
|
||||
- (void)addCleanupBlock:(dispatch_block_t)block {
|
||||
[cleanupBlocks addObject:[block copy]];
|
||||
}
|
||||
|
||||
#pragma mark Temporary Directory
|
||||
|
||||
- (NSURL *)baseTemporaryDirectoryURL {
|
||||
if (_baseTemporaryDirectoryURL == nil) {
|
||||
if (baseTemporaryDirectoryURL == nil) {
|
||||
NSURL *globalTemporaryDirectory = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
|
||||
_baseTemporaryDirectoryURL = [[globalTemporaryDirectory URLByAppendingPathComponent:@"com.github.SquirrelTests"] URLByAppendingPathComponent:[NSProcessInfo.processInfo globallyUniqueString]];
|
||||
|
||||
baseTemporaryDirectoryURL = [[globalTemporaryDirectory URLByAppendingPathComponent:@"com.github.SquirrelTests"] URLByAppendingPathComponent:[NSProcessInfo.processInfo globallyUniqueString]];
|
||||
|
||||
NSError *error = nil;
|
||||
BOOL success = [NSFileManager.defaultManager createDirectoryAtURL:_baseTemporaryDirectoryURL withIntermediateDirectories:YES attributes:nil error:&error];
|
||||
XCTAssertTrue(success, @"Couldn't create temporary directory at %@: %@", _baseTemporaryDirectoryURL, error);
|
||||
BOOL success = [NSFileManager.defaultManager createDirectoryAtURL:baseTemporaryDirectoryURL withIntermediateDirectories:YES attributes:nil error:&error];
|
||||
XCTAssertTrue(success, @"Couldn't create temporary directory at %@: %@", baseTemporaryDirectoryURL, error);
|
||||
|
||||
[self addCleanupBlock:^{
|
||||
[NSFileManager.defaultManager removeItemAtURL:_baseTemporaryDirectoryURL error:NULL];
|
||||
_baseTemporaryDirectoryURL = nil;
|
||||
[NSFileManager.defaultManager removeItemAtURL:baseTemporaryDirectoryURL error:NULL];
|
||||
baseTemporaryDirectoryURL = nil;
|
||||
}];
|
||||
}
|
||||
|
||||
return _baseTemporaryDirectoryURL;
|
||||
return baseTemporaryDirectoryURL;
|
||||
}
|
||||
|
||||
- (NSURL *)temporaryDirectoryURL {
|
||||
@@ -177,7 +154,7 @@ static void SQRLSignalHandler(int sig) {
|
||||
- (NSURL *)testApplicationURL {
|
||||
NSURL *fixtureURL = [self.temporaryDirectoryURL URLByAppendingPathComponent:@"TestApplication.app" isDirectory:YES];
|
||||
if (![NSFileManager.defaultManager fileExistsAtPath:fixtureURL.path]) {
|
||||
NSURL *bundleURL = [[NSBundle bundleForClass:self.class] URLForResource:@"TestApplication" withExtension:@"app"];
|
||||
NSURL *bundleURL = [SQRLTestBundle() URLForResource:@"TestApplication" withExtension:@"app"];
|
||||
XCTAssertNotNil(bundleURL, @"Couldn't find TestApplication.app in test bundle");
|
||||
|
||||
NSError *error = nil;
|
||||
@@ -186,15 +163,6 @@ static void SQRLSignalHandler(int sig) {
|
||||
|
||||
NSURL *testAppLog = [fixtureURL.URLByDeletingLastPathComponent URLByAppendingPathComponent:@"TestApplication.log"];
|
||||
[[NSData data] writeToURL:testAppLog atomically:YES];
|
||||
|
||||
NSTask *readTestApp = [self.class tailTaskWithPaths:[RACSequence return:testAppLog.path]];
|
||||
[readTestApp launch];
|
||||
|
||||
XCTAssertTrue([readTestApp isRunning], @"Could not start task %@ to read %@", readTestApp, testAppLog);
|
||||
|
||||
[self addCleanupBlock:^{
|
||||
[readTestApp terminate];
|
||||
}];
|
||||
}
|
||||
|
||||
return fixtureURL;
|
||||
@@ -204,7 +172,7 @@ static void SQRLSignalHandler(int sig) {
|
||||
NSURL *fixtureURL = self.testApplicationURL;
|
||||
NSBundle *bundle = [NSBundle bundleWithURL:fixtureURL];
|
||||
XCTAssertNotNil(bundle, @"Couldn't open bundle at %@", fixtureURL);
|
||||
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@@ -243,7 +211,7 @@ static void SQRLSignalHandler(int sig) {
|
||||
}
|
||||
|
||||
- (NSURL *)createTestApplicationUpdate {
|
||||
NSURL *originalURL = [[NSBundle bundleForClass:self.class] URLForResource:@"TestApplication 2.1" withExtension:@"app"];
|
||||
NSURL *originalURL = [SQRLTestBundle() URLForResource:@"TestApplication 2.1" withExtension:@"app"];
|
||||
XCTAssertNotNil(originalURL, @"Couldn't find TestApplication update in test bundle");
|
||||
|
||||
NSError *error = nil;
|
||||
@@ -262,7 +230,7 @@ static void SQRLSignalHandler(int sig) {
|
||||
}
|
||||
|
||||
- (id)performWithTestApplicationRequirement:(id (^)(SecRequirementRef requirement))block {
|
||||
NSURL *bundleURL = [[NSBundle bundleForClass:self.class] URLForResource:@"TestApplication" withExtension:@"app"];
|
||||
NSURL *bundleURL = [SQRLTestBundle() URLForResource:@"TestApplication" withExtension:@"app"];
|
||||
XCTAssertNotNil(bundleURL, @"Couldn't find TestApplication.app in test bundle");
|
||||
|
||||
SecStaticCodeRef staticCode = NULL;
|
||||
@@ -285,7 +253,7 @@ static void SQRLSignalHandler(int sig) {
|
||||
}
|
||||
|
||||
- (SQRLCodeSignature *)testApplicationSignature {
|
||||
NSURL *bundleURL = [[NSBundle bundleForClass:self.class] URLForResource:@"TestApplication" withExtension:@"app"];
|
||||
NSURL *bundleURL = [SQRLTestBundle() URLForResource:@"TestApplication" withExtension:@"app"];
|
||||
XCTAssertNotNil(bundleURL, @"Couldn't find TestApplication.app in test bundle");
|
||||
|
||||
NSError *error = nil;
|
||||
@@ -305,11 +273,11 @@ static void SQRLSignalHandler(int sig) {
|
||||
|
||||
- (void)installWithRequest:(SQRLShipItRequest *)request remote:(BOOL)remote {
|
||||
if (remote) {
|
||||
expect([[request writeUsingURL:self.shipItDirectoryManager.shipItStateURL] waitUntilCompleted:NULL]).to.beTruthy();
|
||||
expect(@([[request writeUsingURL:self.shipItDirectoryManager.shipItStateURL] waitUntilCompleted:NULL])).to(beTruthy());
|
||||
|
||||
__block NSError *error = nil;
|
||||
expect([[SQRLShipItLauncher launchPrivileged:NO] waitUntilCompleted:&error]).to.beTruthy();
|
||||
expect(error).to.beNil();
|
||||
expect(@([[SQRLShipItLauncher launchPrivileged:NO] waitUntilCompleted:&error])).to(beTruthy());
|
||||
expect(error).to(beNil());
|
||||
|
||||
[self addCleanupBlock:^{
|
||||
// Remove ShipIt's launchd job so it doesn't relaunch itself.
|
||||
@@ -317,19 +285,19 @@ static void SQRLSignalHandler(int sig) {
|
||||
|
||||
NSError *lookupError;
|
||||
NSURL *stateURL = [[self.shipItDirectoryManager shipItStateURL] firstOrDefault:nil success:NULL error:&lookupError];
|
||||
expect(stateURL).notTo.beNil();
|
||||
expect(lookupError).to.beNil();
|
||||
expect(stateURL).notTo(beNil());
|
||||
expect(lookupError).to(beNil());
|
||||
|
||||
[NSFileManager.defaultManager removeItemAtURL:stateURL error:NULL];
|
||||
}];
|
||||
} else {
|
||||
SQRLInstaller *installer = [[SQRLInstaller alloc] initWithApplicationIdentifier:self.shipItDirectoryManager.applicationIdentifier];
|
||||
expect(installer).notTo.beNil();
|
||||
expect(installer).notTo(beNil());
|
||||
|
||||
NSError *installedError = nil;
|
||||
BOOL installed = [[installer.installUpdateCommand execute:request] asynchronouslyWaitUntilCompleted:&installedError];
|
||||
expect(installed).to.beTruthy();
|
||||
expect(installedError).to.beNil();
|
||||
expect(@(installed)).to(beTruthy());
|
||||
expect(installedError).to(beNil());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,20 +312,24 @@ static void SQRLSignalHandler(int sig) {
|
||||
createInvocation = [NSString stringWithFormat:@"hdiutil create '%@' -fs 'HFS+' -volname '%@' -format UDSP -size 10m -srcfolder '%@' -quiet", destinationURL.path, name, directoryURL.path];
|
||||
}
|
||||
|
||||
expect(system(createInvocation.UTF8String)).to.equal(0);
|
||||
expect(@(system(createInvocation.UTF8String))).to(equal(@0));
|
||||
|
||||
NSString *mountInvocation = [NSString stringWithFormat:@"hdiutil attach '%@.sparseimage' -noverify -noautofsck -readwrite -quiet", destinationURL.path];
|
||||
expect(system(mountInvocation.UTF8String)).to.equal(0);
|
||||
expect(@(system(mountInvocation.UTF8String))).to(equal(@0));
|
||||
|
||||
NSString *path = [NSString stringWithFormat:@"/Volumes/%@", name];
|
||||
[self addCleanupBlock:^{
|
||||
NSString *detachInvocation = [NSString stringWithFormat:@"hdiutil detach '%@' -force -quiet", path];
|
||||
expect(system(detachInvocation.UTF8String)).to.equal(0);
|
||||
expect(@(system(detachInvocation.UTF8String))).to(equal(@0));
|
||||
}];
|
||||
|
||||
return [NSURL fileURLWithPath:path isDirectory:YES];
|
||||
}
|
||||
|
||||
- (BOOL)isRunningOnTravis {
|
||||
return NSProcessInfo.processInfo.environment[@"TRAVIS"] != nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
@@ -6,9 +6,16 @@
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Nimble/Nimble.h>
|
||||
#import <Quick/Quick.h>
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
#import <Squirrel/Squirrel.h>
|
||||
|
||||
#import "SQRLCodeSignature.h"
|
||||
|
||||
SpecBegin(SQRLCodeSignature)
|
||||
#import "QuickSpec+SQRLFixtures.h"
|
||||
|
||||
QuickSpecBegin(SQRLCodeSignatureSpec)
|
||||
|
||||
__block NSBundle *bundle;
|
||||
__block void (^corruptURL)(NSURL *URL);
|
||||
@@ -17,26 +24,26 @@ beforeEach(^{
|
||||
bundle = self.testApplicationBundle;
|
||||
|
||||
corruptURL = ^(NSURL *URL) {
|
||||
expect([@"this bundle is corrupted, yo" writeToURL:bundle.executableURL atomically:YES encoding:NSUTF8StringEncoding error:NULL]).to.beTruthy();
|
||||
expect(@([@"this bundle is corrupted, yo" writeToURL:bundle.executableURL atomically:YES encoding:NSUTF8StringEncoding error:NULL])).to(beTruthy());
|
||||
};
|
||||
});
|
||||
|
||||
it(@"should verify a valid bundle", ^{
|
||||
NSError *error = nil;
|
||||
BOOL success = [[self.testApplicationSignature verifyBundleAtURL:bundle.bundleURL] waitUntilCompleted:&error];
|
||||
expect(success).to.beTruthy();
|
||||
expect(error).to.beNil();
|
||||
expect(@(success)).to(beTruthy());
|
||||
expect(error).to(beNil());
|
||||
});
|
||||
|
||||
it(@"should fail to verify with different code signing requirements", ^{
|
||||
NSError *error = nil;
|
||||
SQRLCodeSignature *signature = [SQRLCodeSignature currentApplicationSignature:&error];
|
||||
expect(signature).notTo.beNil();
|
||||
expect(error).to.beNil();
|
||||
expect(signature).notTo(beNil());
|
||||
expect(error).to(beNil());
|
||||
|
||||
BOOL success = [[signature verifyBundleAtURL:bundle.bundleURL] waitUntilCompleted:&error];
|
||||
expect(success).to.beFalsy();
|
||||
expect(error).notTo.beNil();
|
||||
expect(@(success)).to(beFalsy());
|
||||
expect(error).notTo(beNil());
|
||||
});
|
||||
|
||||
describe(@"code signature changes", ^{
|
||||
@@ -47,15 +54,15 @@ describe(@"code signature changes", ^{
|
||||
});
|
||||
|
||||
it(@"should fail to verify a bundle with a missing code signature", ^{
|
||||
expect([NSFileManager.defaultManager removeItemAtURL:codeSignatureURL error:NULL]).to.beTruthy();
|
||||
expect(@([NSFileManager.defaultManager removeItemAtURL:codeSignatureURL error:NULL])).to(beTruthy());
|
||||
|
||||
NSError *error = nil;
|
||||
BOOL success = [[self.testApplicationSignature verifyBundleAtURL:bundle.bundleURL] waitUntilCompleted:&error];
|
||||
expect(success).to.beFalsy();
|
||||
expect(@(success)).to(beFalsy());
|
||||
|
||||
expect(error).notTo.beNil();
|
||||
expect(error.domain).to.equal(SQRLCodeSignatureErrorDomain);
|
||||
expect(error.code).to.equal(SQRLCodeSignatureErrorDidNotPass);
|
||||
expect(error).notTo(beNil());
|
||||
expect(error.domain).to(equal(SQRLCodeSignatureErrorDomain));
|
||||
expect(@(error.code)).to(equal(@(SQRLCodeSignatureErrorDidNotPass)));
|
||||
});
|
||||
|
||||
it(@"should fail to verify a bundle with a corrupt code signature", ^{
|
||||
@@ -63,25 +70,25 @@ describe(@"code signature changes", ^{
|
||||
|
||||
NSError *error = nil;
|
||||
BOOL success = [[self.testApplicationSignature verifyBundleAtURL:bundle.bundleURL] waitUntilCompleted:&error];
|
||||
expect(success).to.beFalsy();
|
||||
expect(@(success)).to(beFalsy());
|
||||
|
||||
expect(error).notTo.beNil();
|
||||
expect(error.domain).to.equal(SQRLCodeSignatureErrorDomain);
|
||||
expect(error.code).to.equal(SQRLCodeSignatureErrorDidNotPass);
|
||||
expect(error).notTo(beNil());
|
||||
expect(error.domain).to(equal(SQRLCodeSignatureErrorDomain));
|
||||
expect(@(error.code)).to(equal(@(SQRLCodeSignatureErrorDidNotPass)));
|
||||
});
|
||||
});
|
||||
|
||||
describe(@"main executable changes", ^{
|
||||
it(@"should fail to verify a bundle with a missing executable", ^{
|
||||
expect([NSFileManager.defaultManager removeItemAtURL:bundle.executableURL error:NULL]).to.beTruthy();
|
||||
expect(@([NSFileManager.defaultManager removeItemAtURL:bundle.executableURL error:NULL])).to(beTruthy());
|
||||
|
||||
NSError *error = nil;
|
||||
BOOL success = [[self.testApplicationSignature verifyBundleAtURL:bundle.bundleURL] waitUntilCompleted:&error];
|
||||
expect(success).to.beFalsy();
|
||||
expect(@(success)).to(beFalsy());
|
||||
|
||||
expect(error).notTo.beNil();
|
||||
expect(error.domain).to.equal(SQRLCodeSignatureErrorDomain);
|
||||
expect(error.code).to.equal(SQRLCodeSignatureErrorCouldNotCreateStaticCode);
|
||||
expect(error).notTo(beNil());
|
||||
expect(error.domain).to(equal(SQRLCodeSignatureErrorDomain));
|
||||
expect(@(error.code)).to(equal(@(SQRLCodeSignatureErrorCouldNotCreateStaticCode)));
|
||||
});
|
||||
|
||||
it(@"should fail to verify a bundle with a corrupt executable", ^{
|
||||
@@ -89,11 +96,11 @@ describe(@"main executable changes", ^{
|
||||
|
||||
NSError *error = nil;
|
||||
BOOL success = [[self.testApplicationSignature verifyBundleAtURL:bundle.bundleURL] waitUntilCompleted:&error];
|
||||
expect(success).to.beFalsy();
|
||||
expect(@(success)).to(beFalsy());
|
||||
|
||||
expect(error).notTo.beNil();
|
||||
expect(error.domain).to.equal(SQRLCodeSignatureErrorDomain);
|
||||
expect(error.code).to.equal(SQRLCodeSignatureErrorDidNotPass);
|
||||
expect(error).notTo(beNil());
|
||||
expect(error.domain).to(equal(SQRLCodeSignatureErrorDomain));
|
||||
expect(@(error.code)).to(equal(@(SQRLCodeSignatureErrorDidNotPass)));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -102,19 +109,19 @@ describe(@"helper executable changes", ^{
|
||||
|
||||
beforeEach(^{
|
||||
helperURL = [bundle URLForAuxiliaryExecutable:@"unused-helper"];
|
||||
expect(helperURL).notTo.beNil();
|
||||
expect(helperURL).notTo(beNil());
|
||||
});
|
||||
|
||||
it(@"should fail to verify a bundle with a missing helper", ^{
|
||||
expect([NSFileManager.defaultManager removeItemAtURL:helperURL error:NULL]).to.beTruthy();
|
||||
expect(@([NSFileManager.defaultManager removeItemAtURL:helperURL error:NULL])).to(beTruthy());
|
||||
|
||||
NSError *error = nil;
|
||||
BOOL success = [[self.testApplicationSignature verifyBundleAtURL:bundle.bundleURL] waitUntilCompleted:&error];
|
||||
expect(success).to.beFalsy();
|
||||
expect(@(success)).to(beFalsy());
|
||||
|
||||
expect(error).notTo.beNil();
|
||||
expect(error.domain).to.equal(SQRLCodeSignatureErrorDomain);
|
||||
expect(error.code).to.equal(SQRLCodeSignatureErrorDidNotPass);
|
||||
expect(error).notTo(beNil());
|
||||
expect(error.domain).to(equal(SQRLCodeSignatureErrorDomain));
|
||||
expect(@(error.code)).to(equal(@(SQRLCodeSignatureErrorDidNotPass)));
|
||||
});
|
||||
|
||||
it(@"should fail to verify a bundle with a corrupt helper", ^{
|
||||
@@ -122,11 +129,11 @@ describe(@"helper executable changes", ^{
|
||||
|
||||
NSError *error = nil;
|
||||
BOOL success = [[self.testApplicationSignature verifyBundleAtURL:bundle.bundleURL] waitUntilCompleted:&error];
|
||||
expect(success).to.beFalsy();
|
||||
expect(@(success)).to(beFalsy());
|
||||
|
||||
expect(error).notTo.beNil();
|
||||
expect(error.domain).to.equal(SQRLCodeSignatureErrorDomain);
|
||||
expect(error.code).to.equal(SQRLCodeSignatureErrorDidNotPass);
|
||||
expect(error).notTo(beNil());
|
||||
expect(error.domain).to(equal(SQRLCodeSignatureErrorDomain));
|
||||
expect(@(error.code)).to(equal(@(SQRLCodeSignatureErrorDidNotPass)));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -135,19 +142,19 @@ describe(@"resource changes", ^{
|
||||
|
||||
beforeEach(^{
|
||||
resourceURL = [bundle URLForResource:@"MainMenu" withExtension:@"nib"];
|
||||
expect(resourceURL).notTo.beNil();
|
||||
expect(resourceURL).notTo(beNil());
|
||||
});
|
||||
|
||||
it(@"should fail to verify a bundle with a missing resource", ^{
|
||||
expect([NSFileManager.defaultManager removeItemAtURL:resourceURL error:NULL]).to.beTruthy();
|
||||
expect(@([NSFileManager.defaultManager removeItemAtURL:resourceURL error:NULL])).to(beTruthy());
|
||||
|
||||
NSError *error = nil;
|
||||
BOOL success = [[self.testApplicationSignature verifyBundleAtURL:bundle.bundleURL] waitUntilCompleted:&error];
|
||||
expect(success).to.beFalsy();
|
||||
expect(@(success)).to(beFalsy());
|
||||
|
||||
expect(error).notTo.beNil();
|
||||
expect(error.domain).to.equal(SQRLCodeSignatureErrorDomain);
|
||||
expect(error.code).to.equal(SQRLCodeSignatureErrorDidNotPass);
|
||||
expect(error).notTo(beNil());
|
||||
expect(error.domain).to(equal(SQRLCodeSignatureErrorDomain));
|
||||
expect(@(error.code)).to(equal(@(SQRLCodeSignatureErrorDidNotPass)));
|
||||
});
|
||||
|
||||
it(@"should fail to verify a bundle with a corrupt resource", ^{
|
||||
@@ -155,11 +162,11 @@ describe(@"resource changes", ^{
|
||||
|
||||
NSError *error = nil;
|
||||
BOOL success = [[self.testApplicationSignature verifyBundleAtURL:bundle.bundleURL] waitUntilCompleted:&error];
|
||||
expect(success).to.beFalsy();
|
||||
expect(@(success)).to(beFalsy());
|
||||
|
||||
expect(error).notTo.beNil();
|
||||
expect(error.domain).to.equal(SQRLCodeSignatureErrorDomain);
|
||||
expect(error.code).to.equal(SQRLCodeSignatureErrorDidNotPass);
|
||||
expect(error).notTo(beNil());
|
||||
expect(error.domain).to(equal(SQRLCodeSignatureErrorDomain));
|
||||
expect(@(error.code)).to(equal(@(SQRLCodeSignatureErrorDidNotPass)));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -171,15 +178,15 @@ describe(@"framework changes", ^{
|
||||
});
|
||||
|
||||
it(@"should fail to verify a bundle with a missing framework", ^{
|
||||
expect([NSFileManager.defaultManager removeItemAtURL:frameworkURL error:NULL]).to.beTruthy();
|
||||
expect(@([NSFileManager.defaultManager removeItemAtURL:frameworkURL error:NULL])).to(beTruthy());
|
||||
|
||||
NSError *error = nil;
|
||||
BOOL success = [[self.testApplicationSignature verifyBundleAtURL:bundle.bundleURL] waitUntilCompleted:&error];
|
||||
expect(success).to.beFalsy();
|
||||
expect(@(success)).to(beFalsy());
|
||||
|
||||
expect(error).notTo.beNil();
|
||||
expect(error.domain).to.equal(SQRLCodeSignatureErrorDomain);
|
||||
expect(error.code).to.equal(SQRLCodeSignatureErrorDidNotPass);
|
||||
expect(error).notTo(beNil());
|
||||
expect(error.domain).to(equal(SQRLCodeSignatureErrorDomain));
|
||||
expect(@(error.code)).to(equal(@(SQRLCodeSignatureErrorDidNotPass)));
|
||||
});
|
||||
|
||||
it(@"should fail to verify a bundle with a corrupt framework", ^{
|
||||
@@ -187,12 +194,12 @@ describe(@"framework changes", ^{
|
||||
|
||||
NSError *error = nil;
|
||||
BOOL success = [[self.testApplicationSignature verifyBundleAtURL:bundle.bundleURL] waitUntilCompleted:&error];
|
||||
expect(success).to.beFalsy();
|
||||
expect(@(success)).to(beFalsy());
|
||||
|
||||
expect(error).notTo.beNil();
|
||||
expect(error.domain).to.equal(SQRLCodeSignatureErrorDomain);
|
||||
expect(error.code).to.equal(SQRLCodeSignatureErrorDidNotPass);
|
||||
expect(error).notTo(beNil());
|
||||
expect(error.domain).to(equal(SQRLCodeSignatureErrorDomain));
|
||||
expect(@(error.code)).to(equal(@(SQRLCodeSignatureErrorDidNotPass)));
|
||||
});
|
||||
});
|
||||
|
||||
SpecEnd
|
||||
QuickSpecEnd
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
//
|
||||
// SQRLDeepCodesignSpec.m
|
||||
// Squirrel
|
||||
//
|
||||
// Created by Keith Duncan on 2013-09-05.
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
SpecBegin(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();
|
||||
});
|
||||
|
||||
SpecEnd
|
||||
@@ -6,39 +6,44 @@
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Nimble/Nimble.h>
|
||||
#import <Quick/Quick.h>
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
#import <Squirrel/Squirrel.h>
|
||||
|
||||
#import "SQRLDirectoryManager.h"
|
||||
|
||||
SpecBegin(SQRLDirectoryManager)
|
||||
QuickSpecBegin(SQRLDirectoryManagerSpec)
|
||||
|
||||
__block NSString *otestIdentifier;
|
||||
|
||||
beforeEach(^{
|
||||
otestIdentifier = NSRunningApplication.currentApplication.localizedName;
|
||||
expect(otestIdentifier).notTo.beNil();
|
||||
otestIdentifier = NSProcessInfo.processInfo.environment[@"FORCE_APP_IDENTIFIER"];
|
||||
expect(otestIdentifier).notTo(beNil());
|
||||
});
|
||||
|
||||
it(@"should initialize", ^{
|
||||
SQRLDirectoryManager *manager = [[SQRLDirectoryManager alloc] initWithApplicationIdentifier:otestIdentifier];
|
||||
expect(manager).notTo.beNil();
|
||||
expect(manager).notTo(beNil());
|
||||
});
|
||||
|
||||
it(@"should create a manager for the current app", ^{
|
||||
SQRLDirectoryManager *manager = SQRLDirectoryManager.currentApplicationManager;
|
||||
expect(manager).notTo.beNil();
|
||||
expect(manager).to.equal([[SQRLDirectoryManager alloc] initWithApplicationIdentifier:otestIdentifier]);
|
||||
expect(manager).notTo(beNil());
|
||||
expect(manager).to(equal([[SQRLDirectoryManager alloc] initWithApplicationIdentifier:otestIdentifier]));
|
||||
});
|
||||
|
||||
it(@"should send an Application Support URL", ^{
|
||||
SQRLDirectoryManager *manager = SQRLDirectoryManager.currentApplicationManager;
|
||||
|
||||
NSError *error = nil;
|
||||
NSURL *appSupportURL = [[manager applicationSupportURL] firstOrDefault:nil success:NULL error:&error];
|
||||
expect(appSupportURL).notTo.beNil();
|
||||
expect(error).to.beNil();
|
||||
NSURL *appSupportURL = [[manager storageURL] firstOrDefault:nil success:NULL error:&error];
|
||||
expect(appSupportURL).notTo(beNil());
|
||||
expect(error).to(beNil());
|
||||
|
||||
__block BOOL directory = NO;
|
||||
expect([NSFileManager.defaultManager fileExistsAtPath:appSupportURL.path isDirectory:&directory]).to.beTruthy();
|
||||
expect(directory).to.beTruthy();
|
||||
expect(@([NSFileManager.defaultManager fileExistsAtPath:appSupportURL.path isDirectory:&directory])).to(beTruthy());
|
||||
expect(@(directory)).to(beTruthy());
|
||||
});
|
||||
|
||||
it(@"should send a ShipIt state URL", ^{
|
||||
@@ -46,8 +51,8 @@ it(@"should send a ShipIt state URL", ^{
|
||||
|
||||
NSError *error = nil;
|
||||
NSURL *stateURL = [[manager shipItStateURL] firstOrDefault:nil success:NULL error:&error];
|
||||
expect(stateURL).notTo.beNil();
|
||||
expect(error).to.beNil();
|
||||
expect(stateURL).notTo(beNil());
|
||||
expect(error).to(beNil());
|
||||
});
|
||||
|
||||
SpecEnd
|
||||
QuickSpecEnd
|
||||
|
||||
@@ -6,24 +6,29 @@
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Nimble/Nimble.h>
|
||||
#import <Quick/Quick.h>
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
#import <Squirrel/Squirrel.h>
|
||||
|
||||
#import "SQRLCodeSignature.h"
|
||||
#import "SQRLDirectoryManager.h"
|
||||
#import "SQRLInstaller.h"
|
||||
#import "SQRLInstaller+Private.h"
|
||||
#import "SQRLShipItLauncher.h"
|
||||
#import "SQRLShipItRequest.h"
|
||||
#import "SQRLInstallerOwnedBundle.h"
|
||||
#import "SQRLShipItRequest.h"
|
||||
|
||||
SpecBegin(SQRLInstaller)
|
||||
#import "QuickSpec+SQRLFixtures.h"
|
||||
|
||||
QuickSpecBegin(SQRLInstallerSpec)
|
||||
|
||||
mode_t (^modeOfURL)(NSURL *) = ^ mode_t (NSURL *fileURL) {
|
||||
NSFileSecurity *fileSecurity = nil;
|
||||
BOOL success = [fileURL getResourceValue:&fileSecurity forKey:NSURLFileSecurityKey error:NULL];
|
||||
expect(success).to.beTruthy();
|
||||
expect(fileSecurity).notTo.beNil();
|
||||
expect(@(success)).to(beTruthy());
|
||||
expect(fileSecurity).notTo(beNil());
|
||||
|
||||
__block mode_t mode;
|
||||
expect(CFFileSecurityGetMode((__bridge CFFileSecurityRef)fileSecurity, &mode)).to.beTruthy();
|
||||
expect(@(CFFileSecurityGetMode((__bridge CFFileSecurityRef)fileSecurity, &mode))).to(beTruthy());
|
||||
|
||||
return mode & (S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
};
|
||||
@@ -35,75 +40,71 @@ beforeEach(^{
|
||||
});
|
||||
|
||||
it(@"should install an update using ShipIt", ^{
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO];
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO useUpdateBundleName:NO];
|
||||
|
||||
[self installWithRequest:request remote:YES];
|
||||
|
||||
expect(self.testApplicationBundleVersion).will.equal(SQRLTestApplicationUpdatedShortVersionString);
|
||||
expect(self.testApplicationBundleVersion).toEventually(equal(SQRLTestApplicationUpdatedShortVersionString));
|
||||
});
|
||||
|
||||
it(@"should install an update in process", ^{
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO];
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO useUpdateBundleName:NO];
|
||||
|
||||
[self installWithRequest:request remote:NO];
|
||||
|
||||
expect(self.testApplicationBundleVersion).will.equal(SQRLTestApplicationUpdatedShortVersionString);
|
||||
expect(self.testApplicationBundleVersion).toEventually(equal(SQRLTestApplicationUpdatedShortVersionString));
|
||||
});
|
||||
|
||||
it(@"should install an update and relaunch", ^{
|
||||
NSString *bundleIdentifier = @"com.github.Squirrel.TestApplication";
|
||||
NSArray *apps = [NSRunningApplication runningApplicationsWithBundleIdentifier:bundleIdentifier];
|
||||
expect(apps.count).to.equal(0);
|
||||
expect(@(apps.count)).to(equal(@0));
|
||||
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:YES];
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:YES useUpdateBundleName:NO];
|
||||
|
||||
[self installWithRequest:request remote:YES];
|
||||
|
||||
expect(self.testApplicationBundleVersion).will.equal(SQRLTestApplicationUpdatedShortVersionString);
|
||||
expect([NSRunningApplication runningApplicationsWithBundleIdentifier:bundleIdentifier].count).will.equal(1);
|
||||
expect(self.testApplicationBundleVersion).toEventually(equal(SQRLTestApplicationUpdatedShortVersionString));
|
||||
expect(@([NSRunningApplication runningApplicationsWithBundleIdentifier:bundleIdentifier].count)).toEventually(equal(@1));
|
||||
});
|
||||
|
||||
it(@"should install an update from another volume", ^{
|
||||
NSURL *diskImageURL = [self createAndMountDiskImageNamed:@"TestApplication 2.1" fromDirectory:updateURL.URLByDeletingLastPathComponent];
|
||||
updateURL = [diskImageURL URLByAppendingPathComponent:updateURL.lastPathComponent];
|
||||
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO];
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO useUpdateBundleName:NO];
|
||||
|
||||
[self installWithRequest:request remote:YES];
|
||||
|
||||
expect(self.testApplicationBundleVersion).will.equal(SQRLTestApplicationUpdatedShortVersionString);
|
||||
expect(self.testApplicationBundleVersion).toEventually(equal(SQRLTestApplicationUpdatedShortVersionString));
|
||||
});
|
||||
|
||||
it(@"should install an update to another volume", ^{
|
||||
NSURL *diskImageURL = [self createAndMountDiskImageNamed:@"TestApplication" fromDirectory:self.testApplicationURL.URLByDeletingLastPathComponent];
|
||||
NSURL *targetURL = [diskImageURL URLByAppendingPathComponent:self.testApplicationURL.lastPathComponent];
|
||||
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:targetURL bundleIdentifier:nil launchAfterInstallation:NO];
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:targetURL bundleIdentifier:nil launchAfterInstallation:NO useUpdateBundleName:NO];
|
||||
|
||||
[self installWithRequest:request remote:YES];
|
||||
|
||||
NSURL *plistURL = [targetURL URLByAppendingPathComponent:@"Contents/Info.plist"];
|
||||
expect([NSDictionary dictionaryWithContentsOfURL:plistURL][SQRLBundleShortVersionStringKey]).will.equal(SQRLTestApplicationUpdatedShortVersionString);
|
||||
expect([NSDictionary dictionaryWithContentsOfURL:plistURL][SQRLBundleShortVersionStringKey]).withTimeout(SQRLLongTimeout).toEventually(equal(SQRLTestApplicationUpdatedShortVersionString));
|
||||
});
|
||||
|
||||
describe(@"with backup restoration", ^{
|
||||
__block NSURL *targetURL;
|
||||
|
||||
__block SQRLShipItRequest *request;
|
||||
|
||||
beforeEach(^{
|
||||
targetURL = self.testApplicationURL;
|
||||
|
||||
request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:targetURL bundleIdentifier:nil launchAfterInstallation:NO];
|
||||
|
||||
NSURL *copiedTargetURL = [self.temporaryDirectoryURL URLByAppendingPathComponent:@"TestApplication Target.app"];
|
||||
expect([NSFileManager.defaultManager moveItemAtURL:targetURL toURL:copiedTargetURL error:NULL]).to.beTruthy();
|
||||
expect(@([NSFileManager.defaultManager moveItemAtURL:targetURL toURL:copiedTargetURL error:NULL])).to(beTruthy());
|
||||
|
||||
SQRLCodeSignature *codeSignature = self.testApplicationSignature;
|
||||
|
||||
SQRLInstallerOwnedBundle *ownedBundle = [[SQRLInstallerOwnedBundle alloc] initWithOriginalURL:targetURL temporaryURL:copiedTargetURL codeSignature:codeSignature];
|
||||
NSData *ownedBundleArchive = [NSKeyedArchiver archivedDataWithRootObject:ownedBundle];
|
||||
expect(ownedBundleArchive).notTo.beNil();
|
||||
expect(ownedBundleArchive).notTo(beNil());
|
||||
|
||||
// Set up ShipIt's preferences like it paused in the middle of an
|
||||
// installation.
|
||||
@@ -113,56 +114,71 @@ describe(@"with backup restoration", ^{
|
||||
CFPreferencesSetValue((__bridge CFStringRef)SQRLInstallerOwnedBundleKey, (__bridge CFDataRef)ownedBundleArchive, (__bridge CFStringRef)applicationIdentifier, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
|
||||
|
||||
BOOL synchronized = CFPreferencesSynchronize((__bridge CFStringRef)applicationIdentifier, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
|
||||
expect(synchronized).to.beTruthy();
|
||||
});
|
||||
|
||||
afterEach(^{
|
||||
__block NSError *error;
|
||||
expect([[self.testApplicationSignature verifyBundleAtURL:targetURL] waitUntilCompleted:&error]).will.beTruthy();
|
||||
expect(error).to.beNil();
|
||||
|
||||
expect(self.testApplicationBundleVersion).to.equal(SQRLTestApplicationOriginalShortVersionString);
|
||||
expect(@(synchronized)).to(beTruthy());
|
||||
});
|
||||
|
||||
it(@"should not install an update after too many attempts", ^{
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:targetURL bundleIdentifier:nil launchAfterInstallation:NO useUpdateBundleName:NO];
|
||||
[self installWithRequest:request remote:YES];
|
||||
|
||||
__block NSError *error;
|
||||
expect(@([[self.testApplicationSignature verifyBundleAtURL:targetURL] waitUntilCompleted:&error])).toEventually(beTruthy());
|
||||
expect(error).to(beNil());
|
||||
|
||||
expect(self.testApplicationBundleVersion).to(equal(SQRLTestApplicationOriginalShortVersionString));
|
||||
});
|
||||
|
||||
it(@"should relaunch even after failing to install an update", ^{
|
||||
request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:targetURL bundleIdentifier:nil launchAfterInstallation:YES];
|
||||
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:targetURL bundleIdentifier:nil launchAfterInstallation:YES useUpdateBundleName:NO];
|
||||
[self installWithRequest:request remote:YES];
|
||||
|
||||
expect([NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.github.Squirrel.TestApplication"].count).will.equal(1);
|
||||
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());
|
||||
|
||||
expect(self.testApplicationBundleVersion).to(equal(SQRLTestApplicationOriginalShortVersionString));
|
||||
});
|
||||
});
|
||||
|
||||
it(@"should disallow writing the updated application except by the owner", ^{
|
||||
NSString *command = [NSString stringWithFormat:@"chmod -R 0777 '%@'", updateURL.path];
|
||||
expect(system(command.UTF8String)).to.equal(0);
|
||||
expect(@(system(command.UTF8String))).to(equal(@0));
|
||||
|
||||
expect(modeOfURL(updateURL)).to.equal(0777);
|
||||
expect(modeOfURL([updateURL URLByAppendingPathComponent:@"Contents/MacOS/TestApplication"])).to.equal(0777);
|
||||
expect(@(modeOfURL(updateURL))).to(equal(@0777));
|
||||
expect(@(modeOfURL([updateURL URLByAppendingPathComponent:@"Contents/MacOS/TestApplication"]))).to(equal(@0777));
|
||||
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO];
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO useUpdateBundleName:NO];
|
||||
|
||||
[self installWithRequest:request remote:YES];
|
||||
|
||||
expect(self.testApplicationBundleVersion).will.equal(SQRLTestApplicationUpdatedShortVersionString);
|
||||
expect(self.testApplicationBundleVersion).toEventually(equal(SQRLTestApplicationUpdatedShortVersionString));
|
||||
|
||||
expect(modeOfURL(self.testApplicationURL)).to.equal(0755);
|
||||
expect(modeOfURL([self.testApplicationURL URLByAppendingPathComponent:@"Contents/MacOS/TestApplication"])).to.equal(0755);
|
||||
expect(@(modeOfURL(self.testApplicationURL))).to(equal(@0755));
|
||||
expect(@(modeOfURL([self.testApplicationURL URLByAppendingPathComponent:@"Contents/MacOS/TestApplication"]))).to(equal(@0755));
|
||||
});
|
||||
|
||||
describe(@"signal handling", ^{
|
||||
__block NSURL *targetURL;
|
||||
|
||||
void (^verifyUpdate)(void) = ^{
|
||||
// Wait up to the launchd throttle interval, then verify that ShipIt
|
||||
// relaunched and finished installing the update.
|
||||
expect(self.testApplicationBundleVersion).withTimeout(SQRLLongTimeout).toEventually(equal(SQRLTestApplicationUpdatedShortVersionString));
|
||||
|
||||
NSError *error;
|
||||
BOOL success = [[self.testApplicationSignature verifyBundleAtURL:targetURL] waitUntilCompleted:&error];
|
||||
expect(@(success)).to(beTruthy());
|
||||
expect(error).to(beNil());
|
||||
};
|
||||
|
||||
beforeEach(^{
|
||||
// Copied so that we don't recreate the TestApplication bundle by
|
||||
// accessing the property.
|
||||
targetURL = self.testApplicationURL;
|
||||
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO];
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO useUpdateBundleName:NO];
|
||||
|
||||
[self installWithRequest:request remote:YES];
|
||||
|
||||
@@ -172,32 +188,24 @@ describe(@"signal handling", ^{
|
||||
[NSThread sleepForTimeInterval:delay];
|
||||
});
|
||||
|
||||
afterEach(^{
|
||||
// Wait up to the launchd throttle interval, then verify that ShipIt
|
||||
// relaunched and finished installing the update.
|
||||
Expecta.asynchronousTestTimeout = 5;
|
||||
expect(self.testApplicationBundleVersion).will.equal(SQRLTestApplicationUpdatedShortVersionString);
|
||||
|
||||
NSError *error;
|
||||
BOOL success = [[self.testApplicationSignature verifyBundleAtURL:targetURL] waitUntilCompleted:&error];
|
||||
expect(success).to.beTruthy();
|
||||
expect(error).to.beNil();
|
||||
});
|
||||
|
||||
it(@"should handle SIGHUP", ^{
|
||||
system("killall -HUP ShipIt");
|
||||
verifyUpdate();
|
||||
});
|
||||
|
||||
it(@"should handle SIGTERM", ^{
|
||||
system("killall -TERM ShipIt");
|
||||
verifyUpdate();
|
||||
});
|
||||
|
||||
it(@"should handle SIGINT", ^{
|
||||
system("killall -INT ShipIt");
|
||||
verifyUpdate();
|
||||
});
|
||||
|
||||
it(@"should handle SIGQUIT", ^{
|
||||
system("killall -QUIT ShipIt");
|
||||
verifyUpdate();
|
||||
});
|
||||
|
||||
it(@"should handle SIGKILL", ^{
|
||||
@@ -213,7 +221,9 @@ describe(@"signal handling", ^{
|
||||
NSTimeInterval delay = 2 + (arc4random_uniform(100) / 1000.0);
|
||||
[NSThread sleepForTimeInterval:delay];
|
||||
}
|
||||
|
||||
verifyUpdate();
|
||||
});
|
||||
});
|
||||
|
||||
SpecEnd
|
||||
QuickSpecEnd
|
||||
|
||||
@@ -6,10 +6,17 @@
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Nimble/Nimble.h>
|
||||
#import <Quick/Quick.h>
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
#import <Squirrel/Squirrel.h>
|
||||
|
||||
#import "SQRLDirectoryManager.h"
|
||||
#import "SQRLShipItRequest.h"
|
||||
|
||||
SpecBegin(SQRLShipItRequest)
|
||||
#import "QuickSpec+SQRLFixtures.h"
|
||||
|
||||
QuickSpecBegin(SQRLShipItRequestSpec)
|
||||
|
||||
__block SQRLDirectoryManager *directoryManager;
|
||||
__block SQRLShipItRequest *request;
|
||||
@@ -18,46 +25,46 @@ beforeEach(^{
|
||||
directoryManager = SQRLDirectoryManager.currentApplicationManager;
|
||||
|
||||
NSURL *updateURL = [self createTestApplicationUpdate];
|
||||
request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO];
|
||||
expect(request).notTo.beNil();
|
||||
request = [[SQRLShipItRequest alloc] initWithUpdateBundleURL:updateURL targetBundleURL:self.testApplicationURL bundleIdentifier:nil launchAfterInstallation:NO useUpdateBundleName:NO];
|
||||
expect(request).notTo(beNil());
|
||||
|
||||
expect(request.targetBundleURL).to.equal(self.testApplicationURL);
|
||||
expect(request.updateBundleURL).to.equal(updateURL);
|
||||
expect(request.bundleIdentifier).to.beNil();
|
||||
expect(request.launchAfterInstallation).to.beFalsy();
|
||||
expect(request.targetBundleURL).to(equal(self.testApplicationURL));
|
||||
expect(request.updateBundleURL).to(equal(updateURL));
|
||||
expect(request.bundleIdentifier).to(beNil());
|
||||
expect(@(request.launchAfterInstallation)).to(beFalsy());
|
||||
});
|
||||
|
||||
afterEach(^{
|
||||
NSURL *stateURL = [[directoryManager shipItStateURL] first];
|
||||
expect(stateURL).notTo.beNil();
|
||||
|
||||
expect(stateURL).notTo(beNil());
|
||||
|
||||
[NSFileManager.defaultManager removeItemAtURL:stateURL error:NULL];
|
||||
});
|
||||
|
||||
it(@"should copy", ^{
|
||||
SQRLShipItRequest *requestCopy = [request copy];
|
||||
expect(requestCopy).to.equal(request);
|
||||
expect(requestCopy).notTo.beIdenticalTo(request);
|
||||
expect(requestCopy).to(equal(request));
|
||||
expect(requestCopy).notTo(beIdenticalTo(request));
|
||||
});
|
||||
|
||||
it(@"should fail to read state when no file exists yet", ^{
|
||||
NSError *error;
|
||||
BOOL success = [[SQRLShipItRequest readUsingURL:directoryManager.shipItStateURL] waitUntilCompleted:&error];
|
||||
expect(success).to.beFalsy();
|
||||
expect(error).notTo.beNil();
|
||||
expect(@(success)).to(beFalsy());
|
||||
expect(error).notTo(beNil());
|
||||
});
|
||||
|
||||
it(@"should write and read state to disk", ^{
|
||||
NSError *error;
|
||||
BOOL success = [[request writeUsingURL:directoryManager.shipItStateURL] waitUntilCompleted:&error];
|
||||
expect(success).to.beTruthy();
|
||||
expect(error).to.beNil();
|
||||
expect(@(success)).to(beTruthy());
|
||||
expect(error).to(beNil());
|
||||
|
||||
SQRLShipItRequest *readRequest = [[SQRLShipItRequest readUsingURL:directoryManager.shipItStateURL] firstOrDefault:nil success:&success error:&error];
|
||||
expect(success).to.beTruthy();
|
||||
expect(error).to.beNil();
|
||||
expect(@(success)).to(beTruthy());
|
||||
expect(error).to(beNil());
|
||||
|
||||
expect(readRequest).to.equal(request);
|
||||
expect(readRequest).to(equal(request));
|
||||
});
|
||||
|
||||
it(@"should fail gracefully with archives encoding a different class", ^{
|
||||
@@ -65,15 +72,15 @@ it(@"should fail gracefully with archives encoding a different class", ^{
|
||||
|
||||
NSError *error;
|
||||
BOOL write = [[NSKeyedArchiver archivedDataWithRootObject:@"rogue object"] writeToURL:archiveLocation atomically:YES];
|
||||
expect(write).to.beTruthy();
|
||||
expect(error).to.beNil();
|
||||
expect(@(write)).to(beTruthy());
|
||||
expect(error).to(beNil());
|
||||
|
||||
BOOL success = NO;
|
||||
SQRLShipItRequest *request = [[SQRLShipItRequest readUsingURL:[RACSignal return:archiveLocation]] firstOrDefault:nil success:&success error:&error];
|
||||
expect(request).to.beNil();
|
||||
expect(success).to.beFalsy();
|
||||
expect(error.domain).to.equal(SQRLShipItRequestErrorDomain);
|
||||
expect(error.code).to.equal(SQRLShipItRequestErrorUnarchiving);
|
||||
expect(request).to(beNil());
|
||||
expect(@(success)).to(beFalsy());
|
||||
expect(error.domain).to(equal(SQRLShipItRequestErrorDomain));
|
||||
expect(@(error.code)).to(equal(@(SQRLShipItRequestErrorUnarchiving)));
|
||||
});
|
||||
|
||||
SpecEnd
|
||||
QuickSpecEnd
|
||||
|
||||
@@ -6,15 +6,22 @@
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Nimble/Nimble.h>
|
||||
#import <Quick/Quick.h>
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
#import <Squirrel/Squirrel.h>
|
||||
|
||||
#import "SQRLTerminationListener.h"
|
||||
|
||||
SpecBegin(SQRLTerminationListener)
|
||||
#import "QuickSpec+SQRLFixtures.h"
|
||||
|
||||
QuickSpecBegin(SQRLTerminationListenerSpec)
|
||||
|
||||
__block SQRLTerminationListener *listener;
|
||||
|
||||
beforeEach(^{
|
||||
listener = [[SQRLTerminationListener alloc] initWithURL:self.testApplicationURL bundleIdentifier:self.testApplicationBundle.bundleIdentifier];
|
||||
expect(listener).notTo.beNil();
|
||||
expect(listener).notTo(beNil());
|
||||
});
|
||||
|
||||
it(@"should complete immediately when the app is not running", ^{
|
||||
@@ -23,10 +30,12 @@ it(@"should complete immediately when the app is not running", ^{
|
||||
completed = YES;
|
||||
}];
|
||||
|
||||
expect(completed).to.beTruthy();
|
||||
expect(@(completed)).to(beTruthy());
|
||||
});
|
||||
|
||||
it(@"should wait until one instance terminates", ^{
|
||||
SKIP_IF_RUNNING_ON_TRAVIS
|
||||
|
||||
NSRunningApplication *app = [self launchTestApplicationWithEnvironment:nil];
|
||||
|
||||
__block NSRunningApplication *observedApp = nil;
|
||||
@@ -37,15 +46,17 @@ it(@"should wait until one instance terminates", ^{
|
||||
completed = YES;
|
||||
}];
|
||||
|
||||
expect(observedApp).will.equal(app);
|
||||
expect(completed).to.beFalsy();
|
||||
expect(observedApp).toEventually(equal(app));
|
||||
expect(@(completed)).to(beFalsy());
|
||||
|
||||
[app forceTerminate];
|
||||
expect(app.terminated).will.beTruthy();
|
||||
expect(completed).will.beTruthy();
|
||||
expect(@(app.terminated)).toEventually(beTruthy());
|
||||
expect(@(completed)).toEventually(beTruthy());
|
||||
});
|
||||
|
||||
it(@"should wait until multiple instances terminate", ^{
|
||||
SKIP_IF_RUNNING_ON_TRAVIS
|
||||
|
||||
NSRunningApplication *app1 = [self launchTestApplicationWithEnvironment:nil];
|
||||
NSRunningApplication *app2 = [self launchTestApplicationWithEnvironment:nil];
|
||||
|
||||
@@ -54,15 +65,15 @@ it(@"should wait until multiple instances terminate", ^{
|
||||
completed = YES;
|
||||
}];
|
||||
|
||||
expect(completed).to.beFalsy();
|
||||
expect(@(completed)).to(beFalsy());
|
||||
|
||||
[app1 forceTerminate];
|
||||
expect(app1.terminated).will.beTruthy();
|
||||
expect(completed).to.beFalsy();
|
||||
expect(@(app1.terminated)).toEventually(beTruthy());
|
||||
expect(@(completed)).to(beFalsy());
|
||||
|
||||
[app2 forceTerminate];
|
||||
expect(app2.terminated).will.beTruthy();
|
||||
expect(completed).will.beTruthy();
|
||||
expect(@(app2.terminated)).toEventually(beTruthy());
|
||||
expect(@(completed)).toEventually(beTruthy());
|
||||
});
|
||||
|
||||
SpecEnd
|
||||
QuickSpecEnd
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
//
|
||||
// SQRLTestHelper.h
|
||||
// Squirrel
|
||||
//
|
||||
// Created by Matt Diephouse on 7/7/14.
|
||||
// Copyright (c) 2014 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/// A test helper class that will run cleanup blocks after each test finishes.
|
||||
@interface SQRLTestHelper : NSObject
|
||||
|
||||
/// Adds a cleanup block that will run after the next test completes.
|
||||
+ (void)addCleanupBlock:(dispatch_block_t)block;
|
||||
|
||||
@end
|
||||
@@ -1,42 +0,0 @@
|
||||
//
|
||||
// SQRLTestHelper.m
|
||||
// Squirrel
|
||||
//
|
||||
// Created by Matt Diephouse on 7/7/14.
|
||||
// Copyright (c) 2014 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SQRLTestHelper.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
@implementation SQRLTestHelper
|
||||
|
||||
#pragma mark - Specta Methods
|
||||
|
||||
+ (void)afterEach {
|
||||
// Enumerate backwards, so later resources are cleaned up first.
|
||||
for (dispatch_block_t block in self.cleanupBlocks.reverseObjectEnumerator) {
|
||||
block();
|
||||
}
|
||||
[self.cleanupBlocks removeAllObjects];
|
||||
}
|
||||
|
||||
#pragma mark - Public Methods
|
||||
|
||||
+ (void)addCleanupBlock:(dispatch_block_t)block {
|
||||
[self.cleanupBlocks addObject:[block copy]];
|
||||
}
|
||||
|
||||
#pragma mark - Private Methods
|
||||
|
||||
+ (NSMutableArray *)cleanupBlocks {
|
||||
NSMutableArray *blocks = objc_getAssociatedObject(self, "sqrl_cleanupBlocks");
|
||||
if (blocks == nil) {
|
||||
blocks = [NSMutableArray array];
|
||||
objc_setAssociatedObject(self, "sqrl_cleanupBlocks", blocks, OBJC_ASSOCIATION_RETAIN);
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -6,22 +6,27 @@
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
SpecBegin(SQRLUpdate)
|
||||
#import <Nimble/Nimble.h>
|
||||
#import <Quick/Quick.h>
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
#import <Squirrel/Squirrel.h>
|
||||
|
||||
QuickSpecBegin(SQRLUpdateSpec)
|
||||
|
||||
it(@"should return nil when initialised without a url", ^{
|
||||
NSError *error = nil;
|
||||
SQRLUpdate *update = [[SQRLUpdate alloc] initWithDictionary:@{} error:&error];
|
||||
expect(update).to.beNil();
|
||||
expect(error.domain).to.equal(NSCocoaErrorDomain);
|
||||
expect(error.code).to.equal(NSKeyValueValidationError);
|
||||
expect(update).to(beNil());
|
||||
expect(error.domain).to(equal(NSCocoaErrorDomain));
|
||||
expect(@(error.code)).to(equal(@(NSKeyValueValidationError)));
|
||||
});
|
||||
|
||||
it(@"should return nil when initialised with a url not in URL syntax", ^{
|
||||
NSError *error = nil;
|
||||
SQRLUpdate *update = [[SQRLUpdate alloc] initWithDictionary:@{ @"updateURL": [NSURL URLWithString:@"test"] } error:&error];
|
||||
expect(update).to.beNil();
|
||||
expect(error.domain).to.equal(NSCocoaErrorDomain);
|
||||
expect(error.code).to.equal(NSKeyValueValidationError);
|
||||
expect(update).to(beNil());
|
||||
expect(error.domain).to(equal(NSCocoaErrorDomain));
|
||||
expect(@(error.code)).to(equal(@(NSKeyValueValidationError)));
|
||||
});
|
||||
|
||||
it(@"should validate release name and notes", ^{
|
||||
@@ -32,20 +37,20 @@ it(@"should validate release name and notes", ^{
|
||||
@"releaseNotes": [[NSObject alloc] init]
|
||||
} error:NULL];
|
||||
|
||||
expect(update).notTo.beNil();
|
||||
expect(update.updateURL).to.equal(updateURL);
|
||||
expect(update.releaseName).to.beNil();
|
||||
expect(update.releaseNotes).to.beNil();
|
||||
expect(update).notTo(beNil());
|
||||
expect(update.updateURL).to(equal(updateURL));
|
||||
expect(update.releaseName).to(beNil());
|
||||
expect(update.releaseNotes).to(beNil());
|
||||
});
|
||||
|
||||
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]));
|
||||
});
|
||||
|
||||
SpecEnd
|
||||
QuickSpecEnd
|
||||
|
||||
@@ -6,38 +6,44 @@
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Nimble/Nimble.h>
|
||||
#import <Quick/Quick.h>
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
#import <Squirrel/Squirrel.h>
|
||||
|
||||
#import "SQRLDirectoryManager.h"
|
||||
#import "SQRLZipArchiver.h"
|
||||
|
||||
#import "SQRLTestUpdate.h"
|
||||
#import "OHHTTPStubs/OHHTTPStubs.h"
|
||||
#import "QuickSpec+SQRLFixtures.h"
|
||||
#import "SQRLTestUpdate.h"
|
||||
#import "TestAppConstants.h"
|
||||
|
||||
SpecBegin(SQRLUpdater)
|
||||
QuickSpecBegin(SQRLUpdaterSpec)
|
||||
|
||||
__block NSURL *JSONURL;
|
||||
|
||||
void (^writeUpdate)(SQRLUpdate *) = ^(SQRLUpdate *update) {
|
||||
NSDictionary *updateInfo = [MTLJSONAdapter JSONDictionaryFromModel:update];
|
||||
expect(updateInfo).notTo.beNil();
|
||||
expect(updateInfo).notTo(beNil());
|
||||
|
||||
NSError *error = nil;
|
||||
NSData *JSON = [NSJSONSerialization dataWithJSONObject:updateInfo options:NSJSONWritingPrettyPrinted error:&error];
|
||||
expect(JSON).notTo.beNil();
|
||||
expect(error).to.beNil();
|
||||
expect(JSON).notTo(beNil());
|
||||
expect(error).to(beNil());
|
||||
|
||||
BOOL success = [JSON writeToURL:JSONURL options:NSDataWritingAtomic error:&error];
|
||||
expect(success).to.beTruthy();
|
||||
expect(error).to.beNil();
|
||||
expect(@(success)).to(beTruthy());
|
||||
expect(error).to(beNil());
|
||||
};
|
||||
|
||||
NSURL * (^zipUpdate)(NSURL *) = ^(NSURL *updateURL) {
|
||||
NSURL *zipFolderURL = [NSFileManager.defaultManager URLForDirectory:NSItemReplacementDirectory inDomain:NSUserDomainMask appropriateForURL:self.temporaryDirectoryURL create:YES error:NULL];
|
||||
expect(zipFolderURL).notTo.beNil();
|
||||
expect(zipFolderURL).notTo(beNil());
|
||||
|
||||
NSURL *zippedUpdateURL = [[zipFolderURL URLByAppendingPathComponent:updateURL.lastPathComponent] URLByAppendingPathExtension:@"zip"];
|
||||
BOOL success = [[SQRLZipArchiver createZipArchiveAtURL:zippedUpdateURL fromDirectoryAtURL:updateURL] asynchronouslyWaitUntilCompleted:NULL];
|
||||
expect(success).to.beTruthy();
|
||||
expect(@(success)).to(beTruthy());
|
||||
|
||||
return zippedUpdateURL;
|
||||
};
|
||||
@@ -55,30 +61,34 @@ beforeEach(^{
|
||||
|
||||
describe(@"updating", ^{
|
||||
__block NSURL *updateURL;
|
||||
|
||||
|
||||
beforeEach(^{
|
||||
updateURL = [self createTestApplicationUpdate];
|
||||
});
|
||||
|
||||
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),
|
||||
@"final": @YES
|
||||
} error:&error];
|
||||
expect(update).notTo.beNil();
|
||||
expect(error).to.beNil();
|
||||
expect(update).notTo(beNil());
|
||||
expect(error).to(beNil());
|
||||
|
||||
writeUpdate(update);
|
||||
|
||||
NSRunningApplication *app = launchWithEnvironment(nil);
|
||||
expect(app.terminated).will.beTruthy();
|
||||
expect(self.testApplicationBundleVersion).will.equal(SQRLTestApplicationUpdatedShortVersionString);
|
||||
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();
|
||||
expect(@([NSFileManager.defaultManager removeItemAtURL:codeSignatureURL error:NULL])).to(beTruthy());
|
||||
|
||||
SQRLTestUpdate *update = [SQRLTestUpdate modelWithDictionary:@{
|
||||
@"updateURL": zipUpdate(updateURL),
|
||||
@@ -88,14 +98,16 @@ describe(@"updating", ^{
|
||||
writeUpdate(update);
|
||||
|
||||
NSRunningApplication *app = launchWithEnvironment(nil);
|
||||
expect(app.terminated).will.beTruthy();
|
||||
expect(@(app.terminated)).withTimeout(SQRLLongTimeout).toEventually(beTruthy());
|
||||
|
||||
// Give the update some time to finish installing.
|
||||
[NSThread sleepForTimeInterval:0.2];
|
||||
expect(self.testApplicationBundleVersion).to.equal(SQRLTestApplicationOriginalShortVersionString);
|
||||
expect(self.testApplicationBundleVersion).to(equal(SQRLTestApplicationOriginalShortVersionString));
|
||||
});
|
||||
|
||||
it(@"should update to the most recently enqueued job", ^{
|
||||
SKIP_IF_RUNNING_ON_TRAVIS
|
||||
|
||||
SQRLTestUpdate *update = [SQRLTestUpdate modelWithDictionary:@{
|
||||
@"updateURL": zipUpdate(self.testApplicationURL)
|
||||
} error:NULL];
|
||||
@@ -119,11 +131,13 @@ describe(@"updating", ^{
|
||||
|
||||
writeUpdate(update);
|
||||
|
||||
expect(app.terminated).will.beTruthy();
|
||||
expect(self.testApplicationBundleVersion).will.equal(SQRLTestApplicationUpdatedShortVersionString);
|
||||
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
|
||||
@@ -131,24 +145,22 @@ describe(@"updating", ^{
|
||||
|
||||
writeUpdate(update);
|
||||
|
||||
NSTimeInterval delay = 30;
|
||||
NSTimeInterval delay = 15;
|
||||
NSRunningApplication *app = launchWithEnvironment(@{ @"SQRLUpdateDelay": [NSString stringWithFormat:@"%f", delay] });
|
||||
|
||||
Expecta.asynchronousTestTimeout = delay + 3;
|
||||
expect(app.terminated).will.beTruthy();
|
||||
|
||||
expect(self.testApplicationBundleVersion).will.equal(SQRLTestApplicationUpdatedShortVersionString);
|
||||
expect(@(app.terminated)).withTimeout(delay + SQRLLongTimeout).toEventually(beTruthy());
|
||||
expect(self.testApplicationBundleVersion).toEventually(equal(SQRLTestApplicationUpdatedShortVersionString));
|
||||
});
|
||||
|
||||
describe(@"cleaning up", ^{
|
||||
__block NSURL *appSupportURL;
|
||||
__block RACSignal *updateDirectoryURLs;
|
||||
|
||||
|
||||
beforeEach(^{
|
||||
SQRLDirectoryManager *directoryManager = [[SQRLDirectoryManager alloc] initWithApplicationIdentifier:@"com.github.Squirrel.TestApplication.ShipIt"];
|
||||
|
||||
appSupportURL = [[directoryManager applicationSupportURL] first];
|
||||
expect(appSupportURL).notTo.beNil();
|
||||
appSupportURL = [[directoryManager storageURL] first];
|
||||
expect(appSupportURL).notTo(beNil());
|
||||
|
||||
updateDirectoryURLs = [[RACSignal
|
||||
defer:^{
|
||||
@@ -163,22 +175,25 @@ describe(@"updating", ^{
|
||||
});
|
||||
|
||||
it(@"should remove downloaded archives after updating", ^{
|
||||
SKIP_IF_RUNNING_ON_TRAVIS
|
||||
|
||||
NSError *error = nil;
|
||||
SQRLTestUpdate *update = [SQRLTestUpdate modelWithDictionary:@{
|
||||
@"updateURL": zipUpdate(updateURL),
|
||||
@"final": @YES
|
||||
} error:&error];
|
||||
|
||||
expect(update).notTo.beNil();
|
||||
expect(error).to.beNil();
|
||||
expect(update).notTo(beNil());
|
||||
expect(error).to(beNil());
|
||||
|
||||
writeUpdate(update);
|
||||
|
||||
NSRunningApplication *app = launchWithEnvironment(nil);
|
||||
expect(app.terminated).will.beTruthy();
|
||||
expect(self.testApplicationBundleVersion).will.equal(SQRLTestApplicationUpdatedShortVersionString);
|
||||
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]).will.equal(@[]);
|
||||
expect([updateDirectoryURLs toArray]).toEventually(equal(@[]));
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -187,7 +202,7 @@ describe(@"response handling", ^{
|
||||
__block NSURLRequest *localRequest = nil;
|
||||
__block SQRLUpdater *updater = nil;
|
||||
|
||||
before(^{
|
||||
beforeEach(^{
|
||||
localRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"fake://host/path"]];
|
||||
updater = [[SQRLUpdater alloc] initWithUpdateRequest:localRequest];
|
||||
});
|
||||
@@ -204,9 +219,9 @@ describe(@"response handling", ^{
|
||||
|
||||
NSError *error = nil;
|
||||
BOOL result = [[updater.checkForUpdatesCommand execute:nil] asynchronouslyWaitUntilCompleted:&error];
|
||||
expect(result).to.beFalsy();
|
||||
expect(error.domain).to.equal(SQRLUpdaterErrorDomain);
|
||||
expect(error.code).to.equal(SQRLUpdaterErrorInvalidServerResponse);
|
||||
expect(@(result)).to(beFalsy());
|
||||
expect(error.domain).to(equal(SQRLUpdaterErrorDomain));
|
||||
expect(@(error.code)).to(equal(@(SQRLUpdaterErrorInvalidServerResponse)));
|
||||
});
|
||||
|
||||
it(@"should return an error for non JSON data", ^{
|
||||
@@ -221,9 +236,9 @@ describe(@"response handling", ^{
|
||||
|
||||
NSError *error = nil;
|
||||
BOOL result = [[updater.checkForUpdatesCommand execute:nil] asynchronouslyWaitUntilCompleted:&error];
|
||||
expect(result).to.beFalsy();
|
||||
expect(error.domain).to.equal(SQRLUpdaterErrorDomain);
|
||||
expect(error.code).to.equal(SQRLUpdaterErrorInvalidServerBody);
|
||||
expect(@(result)).to(beFalsy());
|
||||
expect(error.domain).to(equal(SQRLUpdaterErrorDomain));
|
||||
expect(@(error.code)).to(equal(@(SQRLUpdaterErrorInvalidServerBody)));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -238,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];
|
||||
@@ -250,12 +267,14 @@ describe(@"state", ^{
|
||||
@(SQRLUpdaterStateCheckingForUpdate),
|
||||
@(SQRLUpdaterStateIdle),
|
||||
];
|
||||
expect(states).will.equal(expectedStates);
|
||||
expect(states).toEventually(equal(expectedStates));
|
||||
|
||||
expect(testApplication.terminated).will.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];
|
||||
@@ -266,8 +285,8 @@ describe(@"state", ^{
|
||||
@"updateURL": zipUpdate([self createTestApplicationUpdate]),
|
||||
@"final": @YES,
|
||||
} error:&error];
|
||||
expect(update).notTo.beNil();
|
||||
expect(error).to.beNil();
|
||||
expect(update).notTo(beNil());
|
||||
expect(error).to(beNil());
|
||||
|
||||
writeUpdate(update);
|
||||
|
||||
@@ -279,10 +298,10 @@ describe(@"state", ^{
|
||||
@(SQRLUpdaterStateDownloadingUpdate),
|
||||
@(SQRLUpdaterStateAwaitingRelaunch),
|
||||
];
|
||||
expect(states).will.equal(expectedStates);
|
||||
expect(states).withTimeout(SQRLLongTimeout).toEventually(equal(expectedStates));
|
||||
|
||||
expect(testApplication.terminated).will.beTruthy();
|
||||
expect(@(testApplication.terminated)).withTimeout(SQRLLongTimeout).toEventually(beTruthy());
|
||||
});
|
||||
});
|
||||
|
||||
SpecEnd
|
||||
QuickSpecEnd
|
||||
|
||||
@@ -6,38 +6,44 @@
|
||||
// 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"
|
||||
#import "SQRLCodeSignature.h"
|
||||
#import "SQRLZipArchiver.h"
|
||||
|
||||
SpecBegin(SQRLZipArchiver)
|
||||
QuickSpecBegin(SQRLZipArchiverSpec)
|
||||
|
||||
it(@"should extract a zip archive created by the Finder", ^{
|
||||
NSURL *zipURL = [[NSBundle bundleForClass:self.class] URLForResource:@"TestApplication.app" withExtension:@"zip"];
|
||||
|
||||
NSError *error = nil;
|
||||
BOOL success = [[SQRLZipArchiver unzipArchiveAtURL:zipURL intoDirectoryAtURL:self.temporaryDirectoryURL] asynchronouslyWaitUntilCompleted:&error];
|
||||
expect(success).to.beTruthy();
|
||||
expect(error).to.beNil();
|
||||
expect(@(success)).to(beTruthy());
|
||||
expect(error).to(beNil());
|
||||
|
||||
NSURL *extractedAppURL = [self.temporaryDirectoryURL URLByAppendingPathComponent:@"TestApplication 2.1.app"];
|
||||
expect([NSFileManager.defaultManager fileExistsAtPath:extractedAppURL.path]).to.beTruthy();
|
||||
expect(@([NSFileManager.defaultManager fileExistsAtPath:extractedAppURL.path])).to(beTruthy());
|
||||
|
||||
success = [[self.testApplicationSignature verifyBundleAtURL:extractedAppURL] waitUntilCompleted:&error];
|
||||
expect(success).to.beTruthy();
|
||||
expect(error).to.beNil();
|
||||
expect(@(success)).to(beTruthy());
|
||||
expect(error).to(beNil());
|
||||
});
|
||||
|
||||
it(@"should fail to extract a nonexistent zip archive", ^{
|
||||
NSError *error = nil;
|
||||
BOOL success = [[SQRLZipArchiver unzipArchiveAtURL:[self.temporaryDirectoryURL URLByAppendingPathComponent:@"foo.zip"] intoDirectoryAtURL:self.temporaryDirectoryURL] asynchronouslyWaitUntilCompleted:&error];
|
||||
expect(success).to.beFalsy();
|
||||
expect(@(success)).to(beFalsy());
|
||||
|
||||
NSLog(@"%@", error);
|
||||
|
||||
expect(error).notTo.beNil();
|
||||
expect(error.domain).to.equal(SQRLZipArchiverErrorDomain);
|
||||
expect(error.code).to.equal(SQRLZipArchiverShellTaskFailed);
|
||||
expect(error.userInfo[SQRLZipArchiverExitCodeErrorKey]).notTo.equal(0);
|
||||
expect(error).notTo(beNil());
|
||||
expect(error.domain).to(equal(SQRLZipArchiverErrorDomain));
|
||||
expect(@(error.code)).to(equal(@(SQRLZipArchiverShellTaskFailed)));
|
||||
expect(error.userInfo[SQRLZipArchiverExitCodeErrorKey]).notTo(equal(0));
|
||||
});
|
||||
|
||||
it(@"should create a zip archive readable by itself", ^{
|
||||
@@ -45,21 +51,21 @@ it(@"should create a zip archive readable by itself", ^{
|
||||
|
||||
NSError *error = nil;
|
||||
BOOL success = [[SQRLZipArchiver createZipArchiveAtURL:zipURL fromDirectoryAtURL:self.testApplicationURL] asynchronouslyWaitUntilCompleted:&error];
|
||||
expect(success).to.beTruthy();
|
||||
expect(error).to.beNil();
|
||||
expect(@(success)).to(beTruthy());
|
||||
expect(error).to(beNil());
|
||||
|
||||
expect([NSFileManager.defaultManager fileExistsAtPath:zipURL.path]).to.beTruthy();
|
||||
expect(@([NSFileManager.defaultManager fileExistsAtPath:zipURL.path])).to(beTruthy());
|
||||
|
||||
success = [[SQRLZipArchiver unzipArchiveAtURL:zipURL intoDirectoryAtURL:self.temporaryDirectoryURL] asynchronouslyWaitUntilCompleted:&error];
|
||||
expect(success).to.beTruthy();
|
||||
expect(error).to.beNil();
|
||||
expect(@(success)).to(beTruthy());
|
||||
expect(error).to(beNil());
|
||||
|
||||
NSURL *extractedAppURL = [self.temporaryDirectoryURL URLByAppendingPathComponent:@"TestApplication.app"];
|
||||
expect([NSFileManager.defaultManager fileExistsAtPath:extractedAppURL.path]).to.beTruthy();
|
||||
expect(@([NSFileManager.defaultManager fileExistsAtPath:extractedAppURL.path])).to(beTruthy());
|
||||
|
||||
success = [[self.testApplicationSignature verifyBundleAtURL:extractedAppURL] waitUntilCompleted:&error];
|
||||
expect(success).to.beTruthy();
|
||||
expect(error).to.beNil();
|
||||
expect(@(success)).to(beTruthy());
|
||||
expect(error).to(beNil());
|
||||
});
|
||||
|
||||
SpecEnd
|
||||
QuickSpecEnd
|
||||
|
||||
@@ -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,28 +0,0 @@
|
||||
//
|
||||
// SquirrelTests-Prefix.pch
|
||||
// Squirrel
|
||||
//
|
||||
// Created by Justin Spahr-Summers on 2013-07-21.
|
||||
// Copyright (c) 2013 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import <Mantle/Mantle.h>
|
||||
#import <ReactiveCocoa/ReactiveCocoa.h>
|
||||
#import <ReactiveCocoa/EXTScope.h>
|
||||
#import <Squirrel/Squirrel.h>
|
||||
|
||||
#define SPT_SUBCLASS SQRLTestCase
|
||||
#import "Specta.h"
|
||||
|
||||
#define EXP_SHORTHAND
|
||||
#import "Expecta.h"
|
||||
|
||||
// Expecta #defines startWith as beginWith, which messes up -startWith: :-(
|
||||
#undef startWith
|
||||
|
||||
#import "SQRLTestCase.h"
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// SwiftSpec.swift
|
||||
// ReactiveCocoa
|
||||
//
|
||||
// Created by Justin Spahr-Summers on 2014-10-14.
|
||||
// Copyright (c) 2014 GitHub. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Nimble
|
||||
import Quick
|
||||
|
||||
// Without this, the Swift stdlib won't be linked into the test target (even if
|
||||
// “Embedded Content Contains Swift Code” is enabled).
|
||||
class SwiftSpec: QuickSpec {
|
||||
override func spec() {
|
||||
expect(true).to(beTruthy())
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
@@ -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>
|
||||
|
||||
+9
-2
@@ -10,7 +10,7 @@ config ()
|
||||
{
|
||||
# A whitespace-separated list of executables that must be present and locatable.
|
||||
: ${REQUIRED_TOOLS="xctool"}
|
||||
|
||||
|
||||
export REQUIRED_TOOLS
|
||||
}
|
||||
|
||||
@@ -28,7 +28,14 @@ main ()
|
||||
check_deps
|
||||
fi
|
||||
|
||||
local submodules=$(git submodule status 2>/dev/null)
|
||||
local submodules=$(git submodule status)
|
||||
local result=$?
|
||||
|
||||
if [ "$result" -ne "0" ]
|
||||
then
|
||||
exit $result
|
||||
fi
|
||||
|
||||
if [ -n "$submodules" ]
|
||||
then
|
||||
echo "*** Updating submodules..."
|
||||
|
||||
Binary file not shown.
+26
-19
@@ -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
|
||||
@@ -140,18 +136,29 @@ build_scheme ()
|
||||
|
||||
local awkstatus=$?
|
||||
|
||||
if [ "$awkstatus" -eq "1" ]
|
||||
then
|
||||
# SDK not found, try for iphonesimulator.
|
||||
sdkflag="-sdk iphonesimulator"
|
||||
|
||||
# Determine whether the unit tests will run with iphonesimulator
|
||||
run_xctool $sdkflag -scheme "$scheme" run-tests | parse_build
|
||||
|
||||
awkstatus=$?
|
||||
|
||||
if [ "$awkstatus" -ne "0" ]
|
||||
then
|
||||
# Unit tests will not run on iphonesimulator.
|
||||
sdkflag=""
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$awkstatus" -ne "0" ]
|
||||
then
|
||||
# Unit tests aren't supported.
|
||||
action=build
|
||||
fi
|
||||
|
||||
if [ "$awkstatus" -eq "1" ]
|
||||
then
|
||||
# Build for iOS.
|
||||
sdkflag="-sdk iphonesimulator"
|
||||
fi
|
||||
|
||||
run_xctool $sdkflag -scheme "$scheme" $action
|
||||
}
|
||||
|
||||
|
||||
@@ -1,199 +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)
|
||||
codesign_with_arguments([ "--sign", identity, "--force", "--preserve-metadata=identifier,entitlements,resource-rules,requirements", "--verbose", target.path ])
|
||||
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.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?(".")
|
||||
|
||||
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!
|
||||
|
||||
targets.each do |target|
|
||||
puts "=> #{target.path}"
|
||||
Codesign::Task.sign(target, codesign_identity)
|
||||
end
|
||||
+1
-3
@@ -2,10 +2,8 @@ BEGIN {
|
||||
FS = "\n";
|
||||
}
|
||||
|
||||
/Targets:/ {
|
||||
/Schemes:/ {
|
||||
while (getline && $0 != "") {
|
||||
if ($0 ~ /Test/) continue;
|
||||
|
||||
sub(/^ +/, "");
|
||||
print "'" $0 "'";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user