|
|
@@ -14,9 +14,9 @@
|
|
|
* limitations under the License.
|
|
|
*/
|
|
|
|
|
|
-import Foundation
|
|
|
-
|
|
|
import ArgumentParser
|
|
|
+import FirebaseManifest
|
|
|
+import Foundation
|
|
|
import Utils
|
|
|
|
|
|
struct PodspecsTester: ParsableCommand {
|
|
|
@@ -25,19 +25,115 @@ struct PodspecsTester: ParsableCommand {
|
|
|
transform: URL.init(fileURLWithPath:))
|
|
|
var gitRoot: URL
|
|
|
|
|
|
+ /// A targeted testing pod, e.g. FirebaseAuth.podspec
|
|
|
+ @Option(help: "A podspec that will be tested.")
|
|
|
+ var podspec: String
|
|
|
+
|
|
|
+ /// The root of the Firebase git repo.
|
|
|
+ @Option(help: "Spec testing log dir", transform: URL.init(fileURLWithPath:))
|
|
|
+ var tempLogDir: URL?
|
|
|
+
|
|
|
+ @Flag(help: "Skip unit tests.")
|
|
|
+ var skipTests: Bool
|
|
|
+
|
|
|
mutating func validate() throws {
|
|
|
guard FileManager.default.fileExists(atPath: gitRoot.path) else {
|
|
|
throw ValidationError("git-root does not exist: \(gitRoot.path)")
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /// Trigger spec test with `spec` under the `workingDir` and return an error
|
|
|
+ /// code and log.
|
|
|
+ ///
|
|
|
+ /// - Parameters:
|
|
|
+ /// - spec: The podspec name, e.g. FirebaseAnalytics.podspec.json.
|
|
|
+ /// - workingDir: The dir of the testing spec.
|
|
|
+ /// - args: A dict including options with its value or/and flags with nil.
|
|
|
+ /// - Returns: A tuple with an error code and log.
|
|
|
+ func specTest(spec: String, workingDir: URL,
|
|
|
+ args: [String: String?]) -> (code: Int32, output: String) {
|
|
|
+ var exitCode: Int32 = 0
|
|
|
+ var logOutput: String = ""
|
|
|
+ // If value is nil, the key will be a flag.
|
|
|
+ let arguments = args.map { key, value in
|
|
|
+ if let v = value {
|
|
|
+ return "--\(key)=\(v)"
|
|
|
+ } else {
|
|
|
+ return "--\(key)"
|
|
|
+ }
|
|
|
+ }.joined(separator: " ")
|
|
|
+ let command =
|
|
|
+ "pod spec lint \(spec) \(arguments) --sources=https://github.com/firebase/SpecsTesting,https://cdn.cocoapods.org/"
|
|
|
+ print(command)
|
|
|
+ let result = Shell.executeCommandFromScript(
|
|
|
+ command,
|
|
|
+ outputToConsole: false,
|
|
|
+ workingDir: workingDir
|
|
|
+ )
|
|
|
+ switch result {
|
|
|
+ case let .error(code, output):
|
|
|
+ print("---- Failed Spec Testing: \(spec) Start ----")
|
|
|
+ print("\(output)")
|
|
|
+ print("---- Failed Spec Testing: \(spec) End ----")
|
|
|
+ exitCode = code
|
|
|
+ logOutput = output
|
|
|
+ case let .success(output):
|
|
|
+ print("\(spec) passed validation.")
|
|
|
+ exitCode = 0
|
|
|
+ logOutput = output
|
|
|
+ }
|
|
|
+
|
|
|
+ if let logDir = tempLogDir {
|
|
|
+ do {
|
|
|
+ try logOutput.write(
|
|
|
+ to: logDir.appendingPathComponent("\(spec).txt"),
|
|
|
+ atomically: true,
|
|
|
+ encoding: String.Encoding.utf8
|
|
|
+ )
|
|
|
+ } catch {
|
|
|
+ print(error)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return (exitCode, logOutput)
|
|
|
+ }
|
|
|
+
|
|
|
func run() throws {
|
|
|
let startDate = Date()
|
|
|
+ var exitCode: Int32 = 0
|
|
|
print("Started at: \(startDate.dateTimeString())")
|
|
|
InitializeSpecTesting.setupRepo(sdkRepoURL: gitRoot)
|
|
|
+ let manifest = FirebaseManifest.shared
|
|
|
+ var minutes = 0
|
|
|
+ var timer: DispatchSourceTimer = {
|
|
|
+ let t = DispatchSource.makeTimerSource()
|
|
|
+ t.schedule(deadline: .now(), repeating: 60)
|
|
|
+ t.setEventHandler(handler: {
|
|
|
+ print("Tests have run \(minutes) min(s).")
|
|
|
+ minutes += 1
|
|
|
+ })
|
|
|
+ return t
|
|
|
+ }()
|
|
|
+ timer.resume()
|
|
|
+ let testingPod = podspec.components(separatedBy: ".")[0]
|
|
|
+ for pod in manifest.pods {
|
|
|
+ if testingPod == pod.name {
|
|
|
+ var args: [String: String?] = [:]
|
|
|
+ args["platforms"] = pod.platforms.joined(separator: ",")
|
|
|
+ if pod.allowWarnings {
|
|
|
+ args.updateValue(nil, forKey: "allow-warnings")
|
|
|
+ }
|
|
|
+ if skipTests {
|
|
|
+ args.updateValue(nil, forKey: "skip-tests")
|
|
|
+ }
|
|
|
+ let code = specTest(spec: podspec, workingDir: gitRoot, args: args).code
|
|
|
+ exitCode = code
|
|
|
+ }
|
|
|
+ }
|
|
|
+ timer.cancel()
|
|
|
let finishDate = Date()
|
|
|
print("Finished at: \(finishDate.dateTimeString()). " +
|
|
|
"Duration: \(startDate.formattedDurationSince(finishDate))")
|
|
|
+ Foundation.exit(exitCode)
|
|
|
}
|
|
|
}
|
|
|
|