158 lines
5.2 KiB
Swift
158 lines
5.2 KiB
Swift
// RubyCommand.swift
|
|
// Copyright (c) 2025 FastlaneTools
|
|
|
|
//
|
|
// ** NOTE **
|
|
// This file is provided by fastlane and WILL be overwritten in future updates
|
|
// If you want to add extra functionality to this project, create a new file in a
|
|
// new group so that it won't be marked for upgrade
|
|
//
|
|
|
|
import Foundation
|
|
|
|
struct RubyCommand: RubyCommandable {
|
|
var type: CommandType { return .action }
|
|
|
|
struct Argument {
|
|
enum ArgType {
|
|
case stringClosure
|
|
|
|
var typeString: String {
|
|
switch self {
|
|
case .stringClosure:
|
|
return "string_closure" // this should match when is in ruby's SocketServerActionCommandExecutor
|
|
}
|
|
}
|
|
}
|
|
|
|
let name: String
|
|
let value: Any?
|
|
let type: ArgType?
|
|
|
|
init(name: String, value: Any?, type: ArgType? = nil) {
|
|
self.name = name
|
|
self.value = value
|
|
self.type = type
|
|
}
|
|
|
|
var hasValue: Bool {
|
|
return value != nil
|
|
}
|
|
|
|
var json: String {
|
|
if let someValue = value {
|
|
let typeJson: String
|
|
if let type = type {
|
|
typeJson = ", \"value_type\" : \"\(type.typeString)\""
|
|
} else {
|
|
typeJson = ""
|
|
}
|
|
|
|
if type == .stringClosure {
|
|
return "{\"name\" : \"\(name)\", \"value\" : \"ignored_for_closure\"\(typeJson)}"
|
|
} else if let array = someValue as? [String] {
|
|
return "{\"name\" : \"\(name)\", \"value\" : \(array)\(typeJson)}"
|
|
} else if let hash = someValue as? [String: Any] {
|
|
let jsonData = try! JSONSerialization.data(withJSONObject: hash, options: [])
|
|
let jsonString = String(data: jsonData, encoding: .utf8)!
|
|
return "{\"name\" : \"\(name)\", \"value\" : \(jsonString)\(typeJson)}"
|
|
} else {
|
|
let dictionary = [
|
|
"name": name,
|
|
"value": someValue,
|
|
]
|
|
let jsonData = try! JSONSerialization.data(withJSONObject: dictionary, options: [])
|
|
let jsonString = String(data: jsonData, encoding: .utf8)!
|
|
return jsonString
|
|
}
|
|
} else {
|
|
// Just exclude this arg if it doesn't have a value
|
|
return ""
|
|
}
|
|
}
|
|
}
|
|
|
|
let commandID: String
|
|
let methodName: String
|
|
let className: String?
|
|
let args: [Argument]
|
|
let id: String = UUID().uuidString
|
|
|
|
var closure: ((String) -> Void)? {
|
|
let callbacks = args.filter { ($0.type != nil) && $0.type == .stringClosure }
|
|
guard let callback = callbacks.first else {
|
|
return nil
|
|
}
|
|
|
|
guard let callbackArgValue = callback.value else {
|
|
return nil
|
|
}
|
|
|
|
guard let callbackClosure = callbackArgValue as? ((String) -> Void) else {
|
|
return nil
|
|
}
|
|
return callbackClosure
|
|
}
|
|
|
|
func callbackClosure(_ callbackArg: String) -> ((String) -> Void)? {
|
|
// WARNING: This will perform the first callback it receives
|
|
let callbacks = args.filter { ($0.type != nil) && $0.type == .stringClosure }
|
|
guard let callback = callbacks.first else {
|
|
verbose(message: "received call to performCallback with \(callbackArg), but no callback available to perform")
|
|
return nil
|
|
}
|
|
|
|
guard let callbackArgValue = callback.value else {
|
|
verbose(message: "received call to performCallback with \(callbackArg), but callback is nil")
|
|
return nil
|
|
}
|
|
|
|
guard let callbackClosure = callbackArgValue as? ((String) -> Void) else {
|
|
verbose(message: "received call to performCallback with \(callbackArg), but callback type is unknown \(callbackArgValue.self)")
|
|
return nil
|
|
}
|
|
return callbackClosure
|
|
}
|
|
|
|
func performCallback(callbackArg: String, socket: SocketClient, completion: @escaping () -> Void) {
|
|
verbose(message: "Performing callback with: \(callbackArg)")
|
|
socket.leave()
|
|
callbackClosure(callbackArg)?(callbackArg)
|
|
completion()
|
|
}
|
|
|
|
var commandJson: String {
|
|
let argsArrayJson = args
|
|
.map { $0.json }
|
|
.filter { $0 != "" }
|
|
|
|
let argsJson: String?
|
|
if !argsArrayJson.isEmpty {
|
|
argsJson = "\"args\" : [\(argsArrayJson.joined(separator: ","))]"
|
|
} else {
|
|
argsJson = nil
|
|
}
|
|
|
|
let commandIDJson = "\"commandID\" : \"\(commandID)\""
|
|
let methodNameJson = "\"methodName\" : \"\(methodName)\""
|
|
|
|
var jsonParts = [commandIDJson, methodNameJson]
|
|
if let argsJson = argsJson {
|
|
jsonParts.append(argsJson)
|
|
}
|
|
|
|
if let className = className {
|
|
let classNameJson = "\"className\" : \"\(className)\""
|
|
jsonParts.append(classNameJson)
|
|
}
|
|
|
|
let commandJsonString = "{\(jsonParts.joined(separator: ","))}"
|
|
|
|
return commandJsonString
|
|
}
|
|
}
|
|
|
|
// Please don't remove the lines below
|
|
// They are used to detect outdated files
|
|
// FastlaneRunnerAPIVersion [0.9.2]
|