fastlane 2.69.2 → 2.69.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/fastlane/lib/fastlane/version.rb +1 -1
  3. data/fastlane/swift/Appfile.swift +17 -0
  4. data/fastlane/swift/ArgumentProcessor.swift +72 -0
  5. data/fastlane/swift/Deliverfile.swift +14 -0
  6. data/fastlane/swift/DeliverfileProtocol.swift +118 -0
  7. data/fastlane/swift/Fastfile.swift +12 -0
  8. data/fastlane/swift/Fastlane.swift +3739 -0
  9. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.pbxproj +409 -0
  10. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  11. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/liebowitz.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  12. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/xcshareddata/xcschemes/FastlaneRunner.xcscheme +103 -0
  13. data/fastlane/swift/Gymfile.swift +14 -0
  14. data/fastlane/swift/GymfileProtocol.swift +86 -0
  15. data/fastlane/swift/LaneFileProtocol.swift +103 -0
  16. data/fastlane/swift/Matchfile.swift +14 -0
  17. data/fastlane/swift/MatchfileProtocol.swift +54 -0
  18. data/fastlane/swift/Precheckfile.swift +14 -0
  19. data/fastlane/swift/PrecheckfileProtocol.swift +24 -0
  20. data/fastlane/swift/RubyCommand.swift +138 -0
  21. data/fastlane/swift/Runner.swift +190 -0
  22. data/fastlane/swift/RunnerArgument.swift +18 -0
  23. data/fastlane/swift/Scanfile.swift +14 -0
  24. data/fastlane/swift/ScanfileProtocol.swift +88 -0
  25. data/fastlane/swift/Screengrabfile.swift +14 -0
  26. data/fastlane/swift/ScreengrabfileProtocol.swift +48 -0
  27. data/fastlane/swift/Snapshotfile.swift +14 -0
  28. data/fastlane/swift/SnapshotfileProtocol.swift +70 -0
  29. data/fastlane/swift/SocketClient.swift +283 -0
  30. data/fastlane/swift/SocketClientDelegateProtocol.swift +19 -0
  31. data/fastlane/swift/SocketResponse.swift +74 -0
  32. data/fastlane/swift/main.swift +43 -0
  33. data/match/lib/match/encrypt.rb +12 -0
  34. metadata +32 -2
@@ -0,0 +1,283 @@
1
+ //
2
+ // SocketClient.swift
3
+ // FastlaneSwiftRunner
4
+ //
5
+ // Created by Joshua Liebowitz on 7/30/17.
6
+ // Copyright © 2017 Joshua Liebowitz. All rights reserved.
7
+ //
8
+
9
+ import Foundation
10
+
11
+ public enum SocketClientResponse: Error {
12
+ case alreadyClosedSockets
13
+ case malformedRequest
14
+ case malformedResponse
15
+ case serverError
16
+ case commandTimeout(seconds: Int)
17
+ case connectionFailure
18
+ case success(returnedObject: String?, closureArgumentValue: String?)
19
+ }
20
+
21
+ class SocketClient: NSObject {
22
+
23
+ enum SocketStatus {
24
+ case ready
25
+ case closed
26
+ }
27
+
28
+ static let connectTimeoutSeconds = 2
29
+ static let defaultCommandTimeoutSeconds = 3_600 // Hopefully 1 hr is enough ¯\_(ツ)_/¯
30
+ static let doneToken = "done"
31
+
32
+ fileprivate var inputStream: InputStream!
33
+ fileprivate var outputStream: OutputStream!
34
+ fileprivate var cleaningUpAfterDone = false
35
+ fileprivate let dispatchGroup: DispatchGroup = DispatchGroup()
36
+ fileprivate let commandTimeoutSeconds: Int
37
+
38
+ private let streamQueue: DispatchQueue
39
+ private let host: String
40
+ private let port: UInt32
41
+
42
+ let maxReadLength = 65_536 // max for ipc on 10.12 is kern.ipc.maxsockbuf: 8388608 ($sysctl kern.ipc.maxsockbuf)
43
+
44
+ weak private(set) var socketDelegate: SocketClientDelegateProtocol?
45
+
46
+ public private(set) var socketStatus: SocketStatus
47
+
48
+ // localhost only, this prevents other computers from connecting
49
+ init(host: String = "localhost", port: UInt32 = 2000, commandTimeoutSeconds: Int = defaultCommandTimeoutSeconds, socketDelegate: SocketClientDelegateProtocol) {
50
+ self.host = host
51
+ self.port = port
52
+ self.commandTimeoutSeconds = commandTimeoutSeconds
53
+ self.streamQueue = DispatchQueue(label: "streamQueue")
54
+ self.socketStatus = .closed
55
+ self.socketDelegate = socketDelegate
56
+ super.init()
57
+ }
58
+
59
+ func connectAndOpenStreams() {
60
+ var readStream: Unmanaged<CFReadStream>?
61
+ var writeStream: Unmanaged<CFWriteStream>?
62
+
63
+ self.streamQueue.async {
64
+ CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, self.host as CFString, self.port, &readStream, &writeStream)
65
+
66
+ self.inputStream = readStream!.takeRetainedValue()
67
+ self.outputStream = writeStream!.takeRetainedValue()
68
+
69
+ self.inputStream.delegate = self
70
+ self.outputStream.delegate = self
71
+
72
+ self.inputStream.schedule(in: .main, forMode: .defaultRunLoopMode)
73
+ self.outputStream.schedule(in: .main, forMode: .defaultRunLoopMode)
74
+ }
75
+
76
+ self.dispatchGroup.enter()
77
+ self.streamQueue.async {
78
+ self.inputStream.open()
79
+ }
80
+
81
+ self.dispatchGroup.enter()
82
+ self.streamQueue.async {
83
+ self.outputStream.open()
84
+ }
85
+
86
+ let secondsToWait = DispatchTimeInterval.seconds(SocketClient.connectTimeoutSeconds)
87
+ let connectTimeout = DispatchTime.now() + secondsToWait
88
+
89
+ let timeoutResult = self.dispatchGroup.wait(timeout: connectTimeout)
90
+ let failureMessage = "Couldn't connect to ruby process within: \(SocketClient.connectTimeoutSeconds) seconds"
91
+
92
+ let success = testDispatchTimeoutResult(timeoutResult, failureMessage: failureMessage, timeToWait: secondsToWait)
93
+
94
+ guard success else {
95
+ self.socketDelegate?.commandExecuted(serverResponse: .connectionFailure)
96
+ return
97
+ }
98
+
99
+ self.socketStatus = .ready
100
+ self.socketDelegate?.connectionsOpened()
101
+ }
102
+
103
+ public func send(rubyCommand: RubyCommandable) {
104
+ verbose(message: "sending: \(rubyCommand.json)")
105
+ send(string: rubyCommand.json)
106
+ }
107
+
108
+ public func sendComplete() {
109
+ sendAbort()
110
+ }
111
+
112
+ private func testDispatchTimeoutResult(_ timeoutResult: DispatchTimeoutResult, failureMessage: String, timeToWait: DispatchTimeInterval) -> Bool {
113
+ switch timeoutResult {
114
+ case .success:
115
+ return true
116
+ case .timedOut:
117
+ log(message: "Timeout: \(failureMessage)")
118
+
119
+ if case .seconds(let seconds) = timeToWait {
120
+ socketDelegate?.commandExecuted(serverResponse: .commandTimeout(seconds: seconds))
121
+ }
122
+ return false
123
+ }
124
+ }
125
+
126
+ private func stopInputSession() {
127
+ inputStream.close()
128
+ }
129
+
130
+ private func stopOutputSession() {
131
+ outputStream.close()
132
+ }
133
+
134
+ private func send(string: String) {
135
+ guard !self.cleaningUpAfterDone else {
136
+ // This will happen after we abort if there are commands waiting to be executed
137
+ // Need to check state of SocketClient in command runner to make sure we can accept `send`
138
+ socketDelegate?.commandExecuted(serverResponse: .alreadyClosedSockets)
139
+ return
140
+ }
141
+
142
+ if string == SocketClient.doneToken {
143
+ self.cleaningUpAfterDone = true
144
+ }
145
+
146
+ self.dispatchGroup.enter()
147
+ streamQueue.async {
148
+ let data = string.data(using: .utf8)!
149
+ _ = data.withUnsafeBytes { self.outputStream.write($0, maxLength: data.count) }
150
+ }
151
+
152
+ let timeoutSeconds = self.cleaningUpAfterDone ? 1 : self.commandTimeoutSeconds
153
+
154
+ let timeToWait = DispatchTimeInterval.seconds(timeoutSeconds)
155
+ let commandTimeout = DispatchTime.now() + timeToWait
156
+ let timeoutResult = self.dispatchGroup.wait(timeout: commandTimeout)
157
+
158
+ _ = testDispatchTimeoutResult(timeoutResult, failureMessage: "Ruby process didn't return after: \(SocketClient.connectTimeoutSeconds) seconds", timeToWait: timeToWait)
159
+ }
160
+
161
+ func sendAbort() {
162
+ self.socketStatus = .closed
163
+
164
+ stopInputSession()
165
+
166
+ // and error occured, let's try to send the "done" message
167
+ send(string: SocketClient.doneToken)
168
+
169
+ stopOutputSession()
170
+ self.socketDelegate?.connectionsClosed()
171
+ }
172
+ }
173
+
174
+ extension SocketClient: StreamDelegate {
175
+ func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
176
+ guard !self.cleaningUpAfterDone else {
177
+ // Still getting response from server eventhough we are done.
178
+ // No big deal, we're closing the streams anyway.
179
+ // That being said, we need to balance out the dispatchGroups
180
+ self.dispatchGroup.leave()
181
+ return
182
+ }
183
+
184
+ if aStream === self.inputStream {
185
+ switch eventCode {
186
+ case Stream.Event.openCompleted:
187
+ self.dispatchGroup.leave()
188
+
189
+ case Stream.Event.errorOccurred:
190
+ verbose(message: "input stream error occurred")
191
+ sendAbort()
192
+
193
+ case Stream.Event.hasBytesAvailable:
194
+ read()
195
+
196
+ case Stream.Event.endEncountered:
197
+ // nothing special here
198
+ break
199
+
200
+ case Stream.Event.hasSpaceAvailable:
201
+ // we don't care about this
202
+ break
203
+
204
+ default:
205
+ verbose(message: "input stream caused unrecognized event: \(eventCode)")
206
+ }
207
+
208
+ } else if aStream === self.outputStream {
209
+ switch eventCode {
210
+ case Stream.Event.openCompleted:
211
+ self.dispatchGroup.leave()
212
+
213
+ case Stream.Event.errorOccurred:
214
+ // probably safe to close all the things because Ruby already disconnected
215
+ verbose(message: "output stream recevied error")
216
+ break
217
+
218
+ case Stream.Event.endEncountered:
219
+ // nothing special here
220
+ break
221
+
222
+ case Stream.Event.hasSpaceAvailable:
223
+ // we don't care about this
224
+ break
225
+
226
+ default:
227
+ verbose(message: "output stream caused unrecognized event: \(eventCode)")
228
+ }
229
+ }
230
+ }
231
+
232
+ func read() {
233
+ var buffer = [UInt8](repeating: 0, count: maxReadLength)
234
+ var output = ""
235
+ while self.inputStream!.hasBytesAvailable {
236
+ let bytesRead: Int = inputStream!.read(&buffer, maxLength: buffer.count)
237
+ if bytesRead >= 0 {
238
+ output += NSString(bytes: UnsafePointer(buffer), length: bytesRead, encoding: String.Encoding.utf8.rawValue)! as String
239
+ } else {
240
+ verbose(message: "Stream read() error")
241
+ }
242
+ }
243
+
244
+ processResponse(string: output)
245
+ }
246
+
247
+ func handleFailure(message: [String]) {
248
+ log(message: "Encountered a problem: \(message.joined(separator:"\n"))")
249
+ sendAbort()
250
+ }
251
+
252
+ func processResponse(string: String) {
253
+ guard string.count > 0 else {
254
+ self.socketDelegate?.commandExecuted(serverResponse: .malformedResponse)
255
+ self.handleFailure(message: ["empty response from ruby process"])
256
+
257
+ return
258
+ }
259
+
260
+ let responseString = string.trimmingCharacters(in: .whitespacesAndNewlines)
261
+ let socketResponse = SocketResponse(payload: responseString)
262
+ verbose(message: "response is: \(responseString)")
263
+ switch socketResponse.responseType {
264
+ case .failure(let failureInformation):
265
+ self.socketDelegate?.commandExecuted(serverResponse: .serverError)
266
+ self.handleFailure(message: failureInformation)
267
+
268
+ case .parseFailure(let failureInformation):
269
+ self.socketDelegate?.commandExecuted(serverResponse: .malformedResponse)
270
+ self.handleFailure(message: failureInformation)
271
+
272
+ case .readyForNext(let returnedObject, let closureArgumentValue):
273
+ self.socketDelegate?.commandExecuted(serverResponse: .success(returnedObject: returnedObject, closureArgumentValue: closureArgumentValue))
274
+ // cool, ready for next command
275
+ break
276
+ }
277
+ self.dispatchGroup.leave() // should now pull the next piece of work
278
+ }
279
+ }
280
+
281
+ // Please don't remove the lines below
282
+ // They are used to detect outdated files
283
+ // FastlaneRunnerAPIVersion [0.9.1]
@@ -0,0 +1,19 @@
1
+ //
2
+ // SocketClientDelegateProtocol.swift
3
+ // FastlaneSwiftRunner
4
+ //
5
+ // Created by Joshua Liebowitz on 8/12/17.
6
+ // Copyright © 2017 Joshua Liebowitz. All rights reserved.
7
+ //
8
+
9
+ import Foundation
10
+
11
+ protocol SocketClientDelegateProtocol: class {
12
+ func connectionsOpened()
13
+ func connectionsClosed()
14
+ func commandExecuted(serverResponse: SocketClientResponse)
15
+ }
16
+
17
+ // Please don't remove the lines below
18
+ // They are used to detect outdated files
19
+ // FastlaneRunnerAPIVersion [0.9.1]
@@ -0,0 +1,74 @@
1
+ //
2
+ // SocketResponse.swift
3
+ // FastlaneSwiftRunner
4
+ //
5
+ // Created by Joshua Liebowitz on 7/30/17.
6
+ // Copyright © 2017 Joshua Liebowitz. All rights reserved.
7
+ //
8
+
9
+ import Foundation
10
+
11
+ struct SocketResponse {
12
+ enum ResponseType {
13
+ case parseFailure(failureInformation: [String])
14
+ case failure(failureInformation: [String])
15
+ case readyForNext(returnedObject: String?, closureArgumentValue: String?)
16
+
17
+ init(statusDictionary: [String : Any]) {
18
+ guard let status = statusDictionary["status"] as? String else {
19
+ self = .parseFailure(failureInformation: ["Message failed to parse from Ruby server"])
20
+ return
21
+ }
22
+
23
+ if status == "ready_for_next" {
24
+ let returnedObject = statusDictionary["return_object"] as? String
25
+ let closureArgumentValue = statusDictionary["closure_argument_value"] as? String
26
+ self = .readyForNext(returnedObject: returnedObject, closureArgumentValue: closureArgumentValue)
27
+ return
28
+
29
+ } else if status == "failure" {
30
+ guard let failureInformation = statusDictionary["failure_information"] as? [String] else {
31
+ self = .parseFailure(failureInformation: ["Ruby server indicated failure but Swift couldn't receive it"])
32
+ return
33
+ }
34
+
35
+ self = .failure(failureInformation: failureInformation)
36
+ return
37
+ }
38
+ self = .parseFailure(failureInformation: ["Message status: \(status) not a supported status"])
39
+ }
40
+ }
41
+
42
+ let responseType: ResponseType
43
+
44
+ init(payload: String) {
45
+ guard let data = SocketResponse.convertToDictionary(text: payload) else {
46
+ self.responseType = .parseFailure(failureInformation: ["Unable to parse message from Ruby server"])
47
+ return
48
+ }
49
+
50
+ guard case let statusDictionary? = data["payload"] as? [String : Any] else {
51
+ self.responseType = .parseFailure(failureInformation: ["Payload missing from Ruby server response"])
52
+ return
53
+ }
54
+
55
+ self.responseType = ResponseType(statusDictionary: statusDictionary)
56
+ }
57
+ }
58
+
59
+ extension SocketResponse {
60
+ static func convertToDictionary(text: String) -> [String : Any]? {
61
+ if let data = text.data(using: .utf8) {
62
+ do {
63
+ return try JSONSerialization.jsonObject(with: data, options: []) as? [String : Any]
64
+ } catch {
65
+ log(message: error.localizedDescription)
66
+ }
67
+ }
68
+ return nil
69
+ }
70
+ }
71
+
72
+ // Please don't remove the lines below
73
+ // They are used to detect outdated files
74
+ // FastlaneRunnerAPIVersion [0.9.1]
@@ -0,0 +1,43 @@
1
+ //
2
+ // main.swift
3
+ // FastlaneSwiftRunner
4
+ //
5
+ // Created by Joshua Liebowitz on 8/26/17.
6
+ // Copyright © 2017 Joshua Liebowitz. All rights reserved.
7
+ //
8
+
9
+ import Foundation
10
+
11
+ let argumentProcessor = ArgumentProcessor(args: CommandLine.arguments)
12
+ let timeout = argumentProcessor.commandTimeout
13
+
14
+ class MainProcess {
15
+ var doneRunningLane = false
16
+ var thread: Thread!
17
+
18
+ @objc func connectToFastlaneAndRunLane() {
19
+ runner.startSocketThread()
20
+
21
+ Fastfile.runLane(named: argumentProcessor.currentLane)
22
+ runner.disconnectFromFastlaneProcess()
23
+
24
+ doneRunningLane = true
25
+ }
26
+
27
+ func startFastlaneThread() {
28
+ thread = Thread(target: self, selector: #selector(connectToFastlaneAndRunLane), object: nil)
29
+ thread.name = "worker thread"
30
+ thread.start()
31
+ }
32
+ }
33
+
34
+ let process: MainProcess = MainProcess()
35
+ process.startFastlaneThread()
36
+
37
+ while (!process.doneRunningLane && (RunLoop.current.run(mode: RunLoopMode.defaultRunLoopMode, before: Date(timeIntervalSinceNow: 2)))) {
38
+ // no op
39
+ }
40
+
41
+ // Please don't remove the lines below
42
+ // They are used to detect outdated files
43
+ // FastlaneRunnerAPIVersion [0.9.1]
@@ -93,6 +93,18 @@ module Match
93
93
  success = system(command.join(' '))
94
94
 
95
95
  UI.crash!("Error decrypting '#{path}'") unless success
96
+
97
+ # On non-Mac systems (more specific Ubuntu Linux) it might take some time for the file to actually be there (see #11182).
98
+ # To try to circumvent this flakyness (in tests), we wait a bit until the file appears (max 2s) (usually only 0.1 is actually waited)
99
+ unless FastlaneCore::Helper.is_mac?
100
+ count = 0
101
+ # sleep until file exists or 20*0.1s (=2s) passed
102
+ until File.exist?(tmpfile) || count == 20
103
+ sleep(0.1)
104
+ count += 1
105
+ end
106
+ end
107
+
96
108
  FileUtils.mv(tmpfile, path)
97
109
  end
98
110
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.69.2
4
+ version: 2.69.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felix Krause
@@ -15,7 +15,7 @@ authors:
15
15
  autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
- date: 2017-12-13 00:00:00.000000000 Z
18
+ date: 2017-12-14 00:00:00.000000000 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: slack-notifier
@@ -1200,6 +1200,36 @@ files:
1200
1200
  - fastlane/lib/fastlane/swift_lane_manager.rb
1201
1201
  - fastlane/lib/fastlane/tools.rb
1202
1202
  - fastlane/lib/fastlane/version.rb
1203
+ - fastlane/swift/Appfile.swift
1204
+ - fastlane/swift/ArgumentProcessor.swift
1205
+ - fastlane/swift/Deliverfile.swift
1206
+ - fastlane/swift/DeliverfileProtocol.swift
1207
+ - fastlane/swift/Fastfile.swift
1208
+ - fastlane/swift/Fastlane.swift
1209
+ - fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.pbxproj
1210
+ - fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
1211
+ - fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/liebowitz.xcuserdatad/UserInterfaceState.xcuserstate
1212
+ - fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/xcshareddata/xcschemes/FastlaneRunner.xcscheme
1213
+ - fastlane/swift/Gymfile.swift
1214
+ - fastlane/swift/GymfileProtocol.swift
1215
+ - fastlane/swift/LaneFileProtocol.swift
1216
+ - fastlane/swift/Matchfile.swift
1217
+ - fastlane/swift/MatchfileProtocol.swift
1218
+ - fastlane/swift/Precheckfile.swift
1219
+ - fastlane/swift/PrecheckfileProtocol.swift
1220
+ - fastlane/swift/RubyCommand.swift
1221
+ - fastlane/swift/Runner.swift
1222
+ - fastlane/swift/RunnerArgument.swift
1223
+ - fastlane/swift/Scanfile.swift
1224
+ - fastlane/swift/ScanfileProtocol.swift
1225
+ - fastlane/swift/Screengrabfile.swift
1226
+ - fastlane/swift/ScreengrabfileProtocol.swift
1227
+ - fastlane/swift/Snapshotfile.swift
1228
+ - fastlane/swift/SnapshotfileProtocol.swift
1229
+ - fastlane/swift/SocketClient.swift
1230
+ - fastlane/swift/SocketClientDelegateProtocol.swift
1231
+ - fastlane/swift/SocketResponse.swift
1232
+ - fastlane/swift/main.swift
1203
1233
  - fastlane_core/README.md
1204
1234
  - fastlane_core/lib/assets/XMLTemplate.xml.erb
1205
1235
  - fastlane_core/lib/fastlane_core.rb