mirror of
https://github.com/jellyfin/Swiftfin.git
synced 2024-11-22 21:49:44 +00:00
Initial fastlane Setup (#1089)
This commit is contained in:
parent
3128a78548
commit
f05ef94c77
21
.github/workflows/draft_release.yml
vendored
Normal file
21
.github/workflows/draft_release.yml
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
on:
|
||||
repository_dispatch:
|
||||
types: [draft_release]
|
||||
|
||||
jobs:
|
||||
test_build:
|
||||
runs-on: macos-14
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.JF_BOT_TOKEN }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Create Release
|
||||
run: fastlane draftReleaseLane \
|
||||
repository:${{ github.event.client_payload.repository }} \
|
||||
apiToken:${{ github.event.client_payload.apiToken }} \
|
||||
tag:${{ github.event.client_payload.tag }} \
|
||||
name64:${{ github.event.client_payload.name64 }}
|
19
.github/workflows/tag.yml
vendored
Normal file
19
.github/workflows/tag.yml
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
on:
|
||||
repository_dispatch:
|
||||
types: [tag]
|
||||
|
||||
jobs:
|
||||
test_build:
|
||||
runs-on: macos-14
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.JF_BOT_TOKEN }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Add Tag
|
||||
run: fastlane tagLane \
|
||||
tag:${{ github.event.client_payload.tag }} \
|
||||
commit:${{ github.event.client_payload.commit }}
|
@ -44,6 +44,6 @@
|
||||
redundantClosure, \
|
||||
redundantType
|
||||
|
||||
--exclude Shared/Strings/Strings.swift
|
||||
--exclude Shared/Strings/Strings.swift, fastlane/
|
||||
|
||||
--header "\nSwiftfin is subject to the terms of the Mozilla Public\nLicense, v2.0. If a copy of the MPL was not distributed with this\nfile, you can obtain one at https://mozilla.org/MPL/2.0/.\n\nCopyright (c) {year} Jellyfin & Jellyfin Contributors\n"
|
||||
|
7
fastlane/Appfile.swift
Normal file
7
fastlane/Appfile.swift
Normal file
@ -0,0 +1,7 @@
|
||||
var appIdentifier: String { return "[[APP_IDENTIFIER]]" } // The bundle identifier of your app
|
||||
var appleID: String { return "[[APPLE_ID]]" } // Your Apple Developer Portal username
|
||||
|
||||
|
||||
|
||||
// For more information about the Appfile, see:
|
||||
// https://docs.fastlane.tools/advanced/#appfile
|
76
fastlane/Fastfile.swift
Normal file
76
fastlane/Fastfile.swift
Normal file
@ -0,0 +1,76 @@
|
||||
// This file contains the fastlane.tools configuration
|
||||
// You can find the documentation at https://docs.fastlane.tools
|
||||
//
|
||||
// For a list of all available actions, check out
|
||||
//
|
||||
// https://docs.fastlane.tools/actions
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class Fastfile: LaneFile {
|
||||
|
||||
// MARK: tag
|
||||
|
||||
func tagLane(withOptions options: [String: String]?) {
|
||||
|
||||
guard let options,
|
||||
let tag = options["tag"] else {
|
||||
puts(message: "ERROR: missing options")
|
||||
exit(1)
|
||||
}
|
||||
|
||||
guard !gitTagExists(tag: tag) else {
|
||||
puts(message: "ERROR: tag \(tag) already exists")
|
||||
exit(1)
|
||||
}
|
||||
|
||||
addGitTag(
|
||||
tag: .userDefined(tag),
|
||||
commit: .userDefined(options["commit"])
|
||||
)
|
||||
|
||||
pushGitTags(
|
||||
force: true
|
||||
)
|
||||
}
|
||||
|
||||
// MARK: draft release
|
||||
|
||||
func draftReleaseLane(withOptions options: [String: String]?) {
|
||||
|
||||
guard let options,
|
||||
let repository = options["repository"],
|
||||
let apiToken = options["apiToken"],
|
||||
let tag = options["tag"],
|
||||
let name64 = options["name64"] else {
|
||||
puts(message: "ERROR: missing options")
|
||||
exit(1)
|
||||
}
|
||||
|
||||
guard let name = decodeBase64(encoded: name64) else {
|
||||
puts(message: "ERROR: name not valid base 64")
|
||||
exit(1)
|
||||
}
|
||||
|
||||
setGithubRelease(
|
||||
repositoryName: repository,
|
||||
apiToken: .userDefined(apiToken),
|
||||
tagName: tag,
|
||||
name: .userDefined(name),
|
||||
isDraft: true,
|
||||
isGenerateReleaseNotes: true
|
||||
)
|
||||
}
|
||||
|
||||
// MARK: Utilities
|
||||
|
||||
private func decodeBase64(encoded: String) -> String? {
|
||||
guard let data = Data(base64Encoded: encoded),
|
||||
let decoded = String(data: data, encoding: .utf8) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return decoded
|
||||
}
|
||||
}
|
16
fastlane/swift/Actions.swift
Normal file
16
fastlane/swift/Actions.swift
Normal file
@ -0,0 +1,16 @@
|
||||
// Actions.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
// This autogenerated file will be overwritten or replaced when running "fastlane generate_swift"
|
||||
//
|
||||
// ** 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
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.56]
|
15
fastlane/swift/Appfile.swift
Normal file
15
fastlane/swift/Appfile.swift
Normal file
@ -0,0 +1,15 @@
|
||||
// Appfile.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
var appIdentifier: String { return "" } // The bundle identifier of your app
|
||||
var appleID: String { return "" } // Your Apple Developer Portal username
|
||||
|
||||
var teamID: String { return "" } // Developer Portal Team ID
|
||||
var itcTeam: String? { return nil } // App Store Connect Team ID (may be nil if no team)
|
||||
|
||||
// you can even provide different app identifiers, Apple IDs and team names per lane:
|
||||
// More information: https://docs.fastlane.tools/advanced/#appfile
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.1]
|
89
fastlane/swift/ArgumentProcessor.swift
Normal file
89
fastlane/swift/ArgumentProcessor.swift
Normal file
@ -0,0 +1,89 @@
|
||||
// ArgumentProcessor.swift
|
||||
// Copyright (c) 2024 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 ArgumentProcessor {
|
||||
let args: [RunnerArgument]
|
||||
let currentLane: String
|
||||
let commandTimeout: Int
|
||||
let port: UInt32
|
||||
|
||||
init(args: [String]) {
|
||||
// Dump the first arg which is the program name
|
||||
let fastlaneArgs = stride(from: 1, to: args.count - 1, by: 2).map {
|
||||
RunnerArgument(name: args[$0], value: args[$0 + 1])
|
||||
}
|
||||
self.args = fastlaneArgs
|
||||
|
||||
let fastlaneArgsMinusLanes = fastlaneArgs.filter { arg in
|
||||
arg.name.lowercased() != "lane"
|
||||
}
|
||||
|
||||
let potentialLogMode = fastlaneArgsMinusLanes.filter { arg in
|
||||
arg.name.lowercased() == "logmode"
|
||||
}
|
||||
|
||||
port = UInt32(fastlaneArgsMinusLanes.first(where: { $0.name == "swiftServerPort" })?.value ?? "") ?? 2000
|
||||
|
||||
// Configure logMode since we might need to use it before we finish parsing
|
||||
if let logModeArg = potentialLogMode.first {
|
||||
let logModeString = logModeArg.value
|
||||
Logger.logMode = Logger.LogMode(logMode: logModeString)
|
||||
}
|
||||
|
||||
let lanes = self.args.filter { arg in
|
||||
arg.name.lowercased() == "lane"
|
||||
}
|
||||
verbose(message: lanes.description)
|
||||
|
||||
guard lanes.count == 1 else {
|
||||
let message = "You must have exactly one lane specified as an arg, here's what I got: \(lanes)"
|
||||
log(message: message)
|
||||
fatalError(message)
|
||||
}
|
||||
|
||||
let lane = lanes.first!
|
||||
currentLane = lane.value
|
||||
|
||||
// User might have configured a timeout for the socket connection
|
||||
let potentialTimeout = fastlaneArgsMinusLanes.filter { arg in
|
||||
arg.name.lowercased() == "timeoutseconds"
|
||||
}
|
||||
|
||||
if let logModeArg = potentialLogMode.first {
|
||||
let logModeString = logModeArg.value
|
||||
Logger.logMode = Logger.LogMode(logMode: logModeString)
|
||||
}
|
||||
|
||||
if let timeoutArg = potentialTimeout.first {
|
||||
let timeoutString = timeoutArg.value
|
||||
commandTimeout = (timeoutString as NSString).integerValue
|
||||
} else {
|
||||
commandTimeout = SocketClient.defaultCommandTimeoutSeconds
|
||||
}
|
||||
}
|
||||
|
||||
func laneParameters() -> [String: String] {
|
||||
let laneParametersArgs = args.filter { arg in
|
||||
let lowercasedName = arg.name.lowercased()
|
||||
return lowercasedName != "timeoutseconds" && lowercasedName != "lane" && lowercasedName != "logmode"
|
||||
}
|
||||
var laneParameters = [String: String]()
|
||||
for arg in laneParametersArgs {
|
||||
laneParameters[arg.name] = arg.value
|
||||
}
|
||||
return laneParameters
|
||||
}
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.2]
|
150
fastlane/swift/Atomic.swift
Normal file
150
fastlane/swift/Atomic.swift
Normal file
@ -0,0 +1,150 @@
|
||||
// Atomic.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol DictionaryProtocol: class {
|
||||
associatedtype Key: Hashable
|
||||
associatedtype Value
|
||||
|
||||
subscript(_: Key) -> Value? { get set }
|
||||
|
||||
@discardableResult
|
||||
func removeValue(forKey key: Key) -> Value?
|
||||
|
||||
func get(_ key: Key) -> Value?
|
||||
func set(_ key: Key, value: Value?)
|
||||
}
|
||||
|
||||
extension DictionaryProtocol {
|
||||
subscript(_ key: Key) -> Value? {
|
||||
get {
|
||||
get(key)
|
||||
}
|
||||
set {
|
||||
set(key, value: newValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protocol LockProtocol: DictionaryProtocol {
|
||||
associatedtype Lock
|
||||
|
||||
var _lock: Lock { get set }
|
||||
|
||||
func lock()
|
||||
func unlock()
|
||||
}
|
||||
|
||||
protocol AnyLock {}
|
||||
|
||||
extension UnsafeMutablePointer: AnyLock {
|
||||
@available(macOS, deprecated: 10.12)
|
||||
static func make() -> Self where Pointee == OSSpinLock {
|
||||
let spin = UnsafeMutablePointer<OSSpinLock>.allocate(capacity: 1)
|
||||
spin.initialize(to: OS_SPINLOCK_INIT)
|
||||
return spin
|
||||
}
|
||||
|
||||
@available(macOS, introduced: 10.12)
|
||||
static func make() -> Self where Pointee == os_unfair_lock {
|
||||
let unfairLock = UnsafeMutablePointer<os_unfair_lock>.allocate(capacity: 1)
|
||||
unfairLock.initialize(to: os_unfair_lock())
|
||||
return unfairLock
|
||||
}
|
||||
|
||||
@available(macOS, deprecated: 10.12)
|
||||
static func lock(_ lock: Self) where Pointee == OSSpinLock {
|
||||
OSSpinLockLock(lock)
|
||||
}
|
||||
|
||||
@available(macOS, deprecated: 10.12)
|
||||
static func unlock(_ lock: Self) where Pointee == OSSpinLock {
|
||||
OSSpinLockUnlock(lock)
|
||||
}
|
||||
|
||||
@available(macOS, introduced: 10.12)
|
||||
static func lock(_ lock: Self) where Pointee == os_unfair_lock {
|
||||
os_unfair_lock_lock(lock)
|
||||
}
|
||||
|
||||
@available(macOS, introduced: 10.12)
|
||||
static func unlock(_ lock: Self) where Pointee == os_unfair_lock {
|
||||
os_unfair_lock_unlock(lock)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Classes
|
||||
|
||||
class AtomicDictionary<Key: Hashable, Value>: LockProtocol {
|
||||
typealias Lock = AnyLock
|
||||
|
||||
var _lock: Lock
|
||||
|
||||
private var storage: [Key: Value] = [:]
|
||||
|
||||
init(_ lock: Lock) {
|
||||
_lock = lock
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func removeValue(forKey key: Key) -> Value? {
|
||||
lock()
|
||||
defer { unlock() }
|
||||
return storage.removeValue(forKey: key)
|
||||
}
|
||||
|
||||
func get(_ key: Key) -> Value? {
|
||||
lock()
|
||||
defer { unlock() }
|
||||
return storage[key]
|
||||
}
|
||||
|
||||
func set(_ key: Key, value: Value?) {
|
||||
lock()
|
||||
defer { unlock() }
|
||||
storage[key] = value
|
||||
}
|
||||
|
||||
func lock() {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
func unlock() {
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
@available(macOS, introduced: 10.12)
|
||||
final class UnfairAtomicDictionary<Key: Hashable, Value>: AtomicDictionary<Key, Value> {
|
||||
typealias Lock = UnsafeMutablePointer<os_unfair_lock>
|
||||
|
||||
init() {
|
||||
super.init(Lock.make())
|
||||
}
|
||||
|
||||
override func lock() {
|
||||
Lock.lock(_lock as! Lock)
|
||||
}
|
||||
|
||||
override func unlock() {
|
||||
Lock.unlock(_lock as! Lock)
|
||||
}
|
||||
}
|
||||
|
||||
@available(macOS, deprecated: 10.12)
|
||||
final class OSSPinAtomicDictionary<Key: Hashable, Value>: AtomicDictionary<Key, Value> {
|
||||
typealias Lock = UnsafeMutablePointer<OSSpinLock>
|
||||
|
||||
init() {
|
||||
super.init(Lock.make())
|
||||
}
|
||||
|
||||
override func lock() {
|
||||
Lock.lock(_lock as! Lock)
|
||||
}
|
||||
|
||||
override func unlock() {
|
||||
Lock.unlock(_lock as! Lock)
|
||||
}
|
||||
}
|
74
fastlane/swift/ControlCommand.swift
Normal file
74
fastlane/swift/ControlCommand.swift
Normal file
@ -0,0 +1,74 @@
|
||||
// ControlCommand.swift
|
||||
// Copyright (c) 2024 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 ControlCommand: RubyCommandable {
|
||||
static let commandKey = "command"
|
||||
var type: CommandType { return .control }
|
||||
|
||||
enum ShutdownCommandType {
|
||||
static let userMessageKey: String = "userMessage"
|
||||
|
||||
enum CancelReason {
|
||||
static let reasonKey: String = "reason"
|
||||
case clientError
|
||||
case serverError
|
||||
|
||||
var reasonText: String {
|
||||
switch self {
|
||||
case .clientError:
|
||||
return "clientError"
|
||||
case .serverError:
|
||||
return "serverError"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case done
|
||||
case cancel(cancelReason: CancelReason)
|
||||
|
||||
var token: String {
|
||||
switch self {
|
||||
case .done:
|
||||
return "done"
|
||||
case .cancel:
|
||||
return "cancelFastlaneRun"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let message: String?
|
||||
let id: String = UUID().uuidString
|
||||
let shutdownCommandType: ShutdownCommandType
|
||||
var commandJson: String {
|
||||
var jsonDictionary: [String: Any] = [ControlCommand.commandKey: shutdownCommandType.token]
|
||||
|
||||
if let message = message {
|
||||
jsonDictionary[ShutdownCommandType.userMessageKey] = message
|
||||
}
|
||||
if case let .cancel(reason) = shutdownCommandType {
|
||||
jsonDictionary[ShutdownCommandType.CancelReason.reasonKey] = reason.reasonText
|
||||
}
|
||||
|
||||
let jsonData = try! JSONSerialization.data(withJSONObject: jsonDictionary, options: [])
|
||||
let jsonString = String(data: jsonData, encoding: .utf8)!
|
||||
return jsonString
|
||||
}
|
||||
|
||||
init(commandType: ShutdownCommandType, message: String? = nil) {
|
||||
shutdownCommandType = commandType
|
||||
self.message = message
|
||||
}
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.2]
|
20
fastlane/swift/Deliverfile.swift
Normal file
20
fastlane/swift/Deliverfile.swift
Normal file
@ -0,0 +1,20 @@
|
||||
// Deliverfile.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
// This class is automatically included in FastlaneRunner during build
|
||||
|
||||
// This autogenerated file will be overwritten or replaced during build time, or when you initialize `deliver`
|
||||
//
|
||||
// ** 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
|
||||
//
|
||||
|
||||
public class Deliverfile: DeliverfileProtocol {
|
||||
// If you want to enable `deliver`, run `fastlane deliver init`
|
||||
// After, this file will be replaced with a custom implementation that contains values you supplied
|
||||
// during the `init` process, and you won't see this message
|
||||
}
|
||||
|
||||
// Generated with fastlane 2.220.0
|
275
fastlane/swift/DeliverfileProtocol.swift
Normal file
275
fastlane/swift/DeliverfileProtocol.swift
Normal file
@ -0,0 +1,275 @@
|
||||
// DeliverfileProtocol.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
public protocol DeliverfileProtocol: AnyObject {
|
||||
/// Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)
|
||||
var apiKeyPath: String? { get }
|
||||
|
||||
/// Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-hash-option)
|
||||
var apiKey: [String: Any]? { get }
|
||||
|
||||
/// Your Apple ID Username
|
||||
var username: String? { get }
|
||||
|
||||
/// The bundle identifier of your app
|
||||
var appIdentifier: String? { get }
|
||||
|
||||
/// The version that should be edited or created
|
||||
var appVersion: String? { get }
|
||||
|
||||
/// Path to your ipa file
|
||||
var ipa: String? { get }
|
||||
|
||||
/// Path to your pkg file
|
||||
var pkg: String? { get }
|
||||
|
||||
/// If set the given build number (already uploaded to iTC) will be used instead of the current built one
|
||||
var buildNumber: String? { get }
|
||||
|
||||
/// The platform to use (optional)
|
||||
var platform: String { get }
|
||||
|
||||
/// Modify live metadata, this option disables ipa upload and screenshot upload
|
||||
var editLive: Bool { get }
|
||||
|
||||
/// Force usage of live version rather than edit version
|
||||
var useLiveVersion: Bool { get }
|
||||
|
||||
/// Path to the folder containing the metadata files
|
||||
var metadataPath: String? { get }
|
||||
|
||||
/// Path to the folder containing the screenshots
|
||||
var screenshotsPath: String? { get }
|
||||
|
||||
/// Skip uploading an ipa or pkg to App Store Connect
|
||||
var skipBinaryUpload: Bool { get }
|
||||
|
||||
/// Don't upload the screenshots
|
||||
var skipScreenshots: Bool { get }
|
||||
|
||||
/// Don't upload the metadata (e.g. title, description). This will still upload screenshots
|
||||
var skipMetadata: Bool { get }
|
||||
|
||||
/// Don’t create or update the app version that is being prepared for submission
|
||||
var skipAppVersionUpdate: Bool { get }
|
||||
|
||||
/// Skip verification of HTML preview file
|
||||
var force: Bool { get }
|
||||
|
||||
/// Clear all previously uploaded screenshots before uploading the new ones
|
||||
var overwriteScreenshots: Bool { get }
|
||||
|
||||
/// Timeout in seconds to wait before considering screenshot processing as failed, used to handle cases where uploads to the App Store are stuck in processing
|
||||
var screenshotProcessingTimeout: Int { get }
|
||||
|
||||
/// Sync screenshots with local ones. This is currently beta option so set true to 'FASTLANE_ENABLE_BETA_DELIVER_SYNC_SCREENSHOTS' environment variable as well
|
||||
var syncScreenshots: Bool { get }
|
||||
|
||||
/// Submit the new version for Review after uploading everything
|
||||
var submitForReview: Bool { get }
|
||||
|
||||
/// Verifies archive with App Store Connect without uploading
|
||||
var verifyOnly: Bool { get }
|
||||
|
||||
/// Rejects the previously submitted build if it's in a state where it's possible
|
||||
var rejectIfPossible: Bool { get }
|
||||
|
||||
/// After submitting a new version, App Store Connect takes some time to recognize the new version and we must wait until it's available before attempting to upload metadata for it. There is a mechanism that will check if it's available and retry with an exponential backoff if it's not available yet. This option specifies how many times we should retry before giving up. Setting this to a value below 5 is not recommended and will likely cause failures. Increase this parameter when Apple servers seem to be degraded or slow
|
||||
var versionCheckWaitRetryLimit: Int { get }
|
||||
|
||||
/// Should the app be automatically released once it's approved? (Cannot be used together with `auto_release_date`)
|
||||
var automaticRelease: Bool? { get }
|
||||
|
||||
/// Date in milliseconds for automatically releasing on pending approval (Cannot be used together with `automatic_release`)
|
||||
var autoReleaseDate: Int? { get }
|
||||
|
||||
/// Enable the phased release feature of iTC
|
||||
var phasedRelease: Bool { get }
|
||||
|
||||
/// Reset the summary rating when you release a new version of the application
|
||||
var resetRatings: Bool { get }
|
||||
|
||||
/// The price tier of this application
|
||||
var priceTier: Int? { get }
|
||||
|
||||
/// Path to the app rating's config
|
||||
var appRatingConfigPath: String? { get }
|
||||
|
||||
/// Extra information for the submission (e.g. compliance specifications, IDFA settings)
|
||||
var submissionInformation: [String: Any]? { get }
|
||||
|
||||
/// The ID of your App Store Connect team if you're in multiple teams
|
||||
var teamId: String? { get }
|
||||
|
||||
/// The name of your App Store Connect team if you're in multiple teams
|
||||
var teamName: String? { get }
|
||||
|
||||
/// The short ID of your Developer Portal team, if you're in multiple teams. Different from your iTC team ID!
|
||||
var devPortalTeamId: String? { get }
|
||||
|
||||
/// The name of your Developer Portal team if you're in multiple teams
|
||||
var devPortalTeamName: String? { get }
|
||||
|
||||
/// The provider short name to be used with the iTMSTransporter to identify your team. This value will override the automatically detected provider short name. To get provider short name run `pathToXcode.app/Contents/Applications/Application\ Loader.app/Contents/itms/bin/iTMSTransporter -m provider -u 'USERNAME' -p 'PASSWORD' -account_type itunes_connect -v off`. The short names of providers should be listed in the second column
|
||||
var itcProvider: String? { get }
|
||||
|
||||
/// Run precheck before submitting to app review
|
||||
var runPrecheckBeforeSubmit: Bool { get }
|
||||
|
||||
/// The default precheck rule level unless otherwise configured
|
||||
var precheckDefaultRuleLevel: String { get }
|
||||
|
||||
/// **DEPRECATED!** Removed after the migration to the new App Store Connect API in June 2020 - An array of localized metadata items to upload individually by language so that errors can be identified. E.g. ['name', 'keywords', 'description']. Note: slow
|
||||
var individualMetadataItems: [String]? { get }
|
||||
|
||||
/// **DEPRECATED!** Removed after the migration to the new App Store Connect API in June 2020 - Metadata: The path to the app icon
|
||||
var appIcon: String? { get }
|
||||
|
||||
/// **DEPRECATED!** Removed after the migration to the new App Store Connect API in June 2020 - Metadata: The path to the Apple Watch app icon
|
||||
var appleWatchAppIcon: String? { get }
|
||||
|
||||
/// Metadata: The copyright notice
|
||||
var copyright: String? { get }
|
||||
|
||||
/// Metadata: The english name of the primary category (e.g. `Business`, `Books`)
|
||||
var primaryCategory: String? { get }
|
||||
|
||||
/// Metadata: The english name of the secondary category (e.g. `Business`, `Books`)
|
||||
var secondaryCategory: String? { get }
|
||||
|
||||
/// Metadata: The english name of the primary first sub category (e.g. `Educational`, `Puzzle`)
|
||||
var primaryFirstSubCategory: String? { get }
|
||||
|
||||
/// Metadata: The english name of the primary second sub category (e.g. `Educational`, `Puzzle`)
|
||||
var primarySecondSubCategory: String? { get }
|
||||
|
||||
/// Metadata: The english name of the secondary first sub category (e.g. `Educational`, `Puzzle`)
|
||||
var secondaryFirstSubCategory: String? { get }
|
||||
|
||||
/// Metadata: The english name of the secondary second sub category (e.g. `Educational`, `Puzzle`)
|
||||
var secondarySecondSubCategory: String? { get }
|
||||
|
||||
/// **DEPRECATED!** This is no longer used by App Store Connect - Metadata: A hash containing the trade representative contact information
|
||||
var tradeRepresentativeContactInformation: [String: Any]? { get }
|
||||
|
||||
/// Metadata: A hash containing the review information
|
||||
var appReviewInformation: [String: Any]? { get }
|
||||
|
||||
/// Metadata: Path to the app review attachment file
|
||||
var appReviewAttachmentFile: String? { get }
|
||||
|
||||
/// Metadata: The localised app description
|
||||
var description: [String: Any]? { get }
|
||||
|
||||
/// Metadata: The localised app name
|
||||
var name: [String: Any]? { get }
|
||||
|
||||
/// Metadata: The localised app subtitle
|
||||
var subtitle: [String: Any]? { get }
|
||||
|
||||
/// Metadata: An array of localised keywords
|
||||
var keywords: [String: Any]? { get }
|
||||
|
||||
/// Metadata: An array of localised promotional texts
|
||||
var promotionalText: [String: Any]? { get }
|
||||
|
||||
/// Metadata: Localised release notes for this version
|
||||
var releaseNotes: [String: Any]? { get }
|
||||
|
||||
/// Metadata: Localised privacy url
|
||||
var privacyUrl: [String: Any]? { get }
|
||||
|
||||
/// Metadata: Localised Apple TV privacy policy text
|
||||
var appleTvPrivacyPolicy: [String: Any]? { get }
|
||||
|
||||
/// Metadata: Localised support url
|
||||
var supportUrl: [String: Any]? { get }
|
||||
|
||||
/// Metadata: Localised marketing url
|
||||
var marketingUrl: [String: Any]? { get }
|
||||
|
||||
/// Metadata: List of languages to activate
|
||||
var languages: [String]? { get }
|
||||
|
||||
/// Ignore errors when invalid languages are found in metadata and screenshot directories
|
||||
var ignoreLanguageDirectoryValidation: Bool { get }
|
||||
|
||||
/// Should precheck check in-app purchases?
|
||||
var precheckIncludeInAppPurchases: Bool { get }
|
||||
|
||||
/// The (spaceship) app ID of the app you want to use/modify
|
||||
var app: Int? { get }
|
||||
}
|
||||
|
||||
public extension DeliverfileProtocol {
|
||||
var apiKeyPath: String? { return nil }
|
||||
var apiKey: [String: Any]? { return nil }
|
||||
var username: String? { return nil }
|
||||
var appIdentifier: String? { return nil }
|
||||
var appVersion: String? { return nil }
|
||||
var ipa: String? { return nil }
|
||||
var pkg: String? { return nil }
|
||||
var buildNumber: String? { return nil }
|
||||
var platform: String { return "ios" }
|
||||
var editLive: Bool { return false }
|
||||
var useLiveVersion: Bool { return false }
|
||||
var metadataPath: String? { return nil }
|
||||
var screenshotsPath: String? { return nil }
|
||||
var skipBinaryUpload: Bool { return false }
|
||||
var skipScreenshots: Bool { return false }
|
||||
var skipMetadata: Bool { return false }
|
||||
var skipAppVersionUpdate: Bool { return false }
|
||||
var force: Bool { return false }
|
||||
var overwriteScreenshots: Bool { return false }
|
||||
var screenshotProcessingTimeout: Int { return 3600 }
|
||||
var syncScreenshots: Bool { return false }
|
||||
var submitForReview: Bool { return false }
|
||||
var verifyOnly: Bool { return false }
|
||||
var rejectIfPossible: Bool { return false }
|
||||
var versionCheckWaitRetryLimit: Int { return 7 }
|
||||
var automaticRelease: Bool? { return nil }
|
||||
var autoReleaseDate: Int? { return nil }
|
||||
var phasedRelease: Bool { return false }
|
||||
var resetRatings: Bool { return false }
|
||||
var priceTier: Int? { return nil }
|
||||
var appRatingConfigPath: String? { return nil }
|
||||
var submissionInformation: [String: Any]? { return nil }
|
||||
var teamId: String? { return nil }
|
||||
var teamName: String? { return nil }
|
||||
var devPortalTeamId: String? { return nil }
|
||||
var devPortalTeamName: String? { return nil }
|
||||
var itcProvider: String? { return nil }
|
||||
var runPrecheckBeforeSubmit: Bool { return true }
|
||||
var precheckDefaultRuleLevel: String { return "warn" }
|
||||
var individualMetadataItems: [String]? { return nil }
|
||||
var appIcon: String? { return nil }
|
||||
var appleWatchAppIcon: String? { return nil }
|
||||
var copyright: String? { return nil }
|
||||
var primaryCategory: String? { return nil }
|
||||
var secondaryCategory: String? { return nil }
|
||||
var primaryFirstSubCategory: String? { return nil }
|
||||
var primarySecondSubCategory: String? { return nil }
|
||||
var secondaryFirstSubCategory: String? { return nil }
|
||||
var secondarySecondSubCategory: String? { return nil }
|
||||
var tradeRepresentativeContactInformation: [String: Any]? { return nil }
|
||||
var appReviewInformation: [String: Any]? { return nil }
|
||||
var appReviewAttachmentFile: String? { return nil }
|
||||
var description: [String: Any]? { return nil }
|
||||
var name: [String: Any]? { return nil }
|
||||
var subtitle: [String: Any]? { return nil }
|
||||
var keywords: [String: Any]? { return nil }
|
||||
var promotionalText: [String: Any]? { return nil }
|
||||
var releaseNotes: [String: Any]? { return nil }
|
||||
var privacyUrl: [String: Any]? { return nil }
|
||||
var appleTvPrivacyPolicy: [String: Any]? { return nil }
|
||||
var supportUrl: [String: Any]? { return nil }
|
||||
var marketingUrl: [String: Any]? { return nil }
|
||||
var languages: [String]? { return nil }
|
||||
var ignoreLanguageDirectoryValidation: Bool { return false }
|
||||
var precheckIncludeInAppPurchases: Bool { return true }
|
||||
var app: Int? { return nil }
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.124]
|
16
fastlane/swift/Fastfile.swift
Normal file
16
fastlane/swift/Fastfile.swift
Normal file
@ -0,0 +1,16 @@
|
||||
// This class is automatically included in FastlaneRunner during build
|
||||
// If you have a custom Fastfile.swift, this file will be replaced by it
|
||||
// Don't modify this file unless you are familiar with how fastlane's swift code generation works
|
||||
// *** This file will be overwritten or replaced during build time ***
|
||||
|
||||
import Foundation
|
||||
|
||||
open class Fastfile: LaneFile {
|
||||
override public init() {
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.1]
|
13800
fastlane/swift/Fastlane.swift
Normal file
13800
fastlane/swift/Fastlane.swift
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,448 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
0311E387230AC1B20060BB5C /* Plugins.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0311E386230AC1B20060BB5C /* Plugins.swift */; };
|
||||
0311E38B230AC9490060BB5C /* Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0311E38A230AC9490060BB5C /* Actions.swift */; };
|
||||
1257253924B7992C00E04FA3 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1257253824B7992B00E04FA3 /* main.swift */; };
|
||||
1267C3F42773A43E004DE48A /* Atomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1267C3F32773A43E004DE48A /* Atomic.swift */; };
|
||||
12D2EB8D2620D83C00844013 /* OptionalConfigValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12D2EB8C2620D83B00844013 /* OptionalConfigValue.swift */; };
|
||||
B302067B1F5E3E9000DE6EBD /* SnapshotfileProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B30206741F5E3E9000DE6EBD /* SnapshotfileProtocol.swift */; };
|
||||
B302067C1F5E3E9000DE6EBD /* GymfileProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B30206751F5E3E9000DE6EBD /* GymfileProtocol.swift */; };
|
||||
B302067D1F5E3E9000DE6EBD /* MatchfileProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B30206761F5E3E9000DE6EBD /* MatchfileProtocol.swift */; };
|
||||
B302067E1F5E3E9000DE6EBD /* PrecheckfileProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B30206771F5E3E9000DE6EBD /* PrecheckfileProtocol.swift */; };
|
||||
B302067F1F5E3E9000DE6EBD /* ScanfileProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B30206781F5E3E9000DE6EBD /* ScanfileProtocol.swift */; };
|
||||
B30206801F5E3E9000DE6EBD /* ScreengrabfileProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B30206791F5E3E9000DE6EBD /* ScreengrabfileProtocol.swift */; };
|
||||
B30206811F5E3E9000DE6EBD /* DeliverfileProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B302067A1F5E3E9000DE6EBD /* DeliverfileProtocol.swift */; };
|
||||
B3BA65A61F5A269100B34850 /* Fastlane.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3BA659D1F5A269100B34850 /* Fastlane.swift */; };
|
||||
B3BA65A71F5A269100B34850 /* LaneFileProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3BA659E1F5A269100B34850 /* LaneFileProtocol.swift */; };
|
||||
B3BA65A91F5A269100B34850 /* RubyCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3BA65A01F5A269100B34850 /* RubyCommand.swift */; };
|
||||
B3BA65AA1F5A269100B34850 /* Runner.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3BA65A11F5A269100B34850 /* Runner.swift */; };
|
||||
B3BA65AB1F5A269100B34850 /* SocketClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3BA65A21F5A269100B34850 /* SocketClient.swift */; };
|
||||
B3BA65AC1F5A269100B34850 /* SocketClientDelegateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3BA65A31F5A269100B34850 /* SocketClientDelegateProtocol.swift */; };
|
||||
B3BA65AD1F5A269100B34850 /* SocketResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3BA65A41F5A269100B34850 /* SocketResponse.swift */; };
|
||||
B3BA65AF1F5A2D5C00B34850 /* RunnerArgument.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3BA65AE1F5A2D5C00B34850 /* RunnerArgument.swift */; };
|
||||
C0459CAC27261897002CDFB9 /* FastlaneRunner in CopyFiles */ = {isa = PBXBuildFile; fileRef = D556D6A91F6A08F5003108E3 /* FastlaneRunner */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
D55B28C31F6C588300DC42C5 /* Deliverfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D55B28BC1F6C588300DC42C5 /* Deliverfile.swift */; };
|
||||
D55B28C41F6C588300DC42C5 /* Gymfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D55B28BD1F6C588300DC42C5 /* Gymfile.swift */; };
|
||||
D55B28C51F6C588300DC42C5 /* Matchfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D55B28BE1F6C588300DC42C5 /* Matchfile.swift */; };
|
||||
D55B28C61F6C588300DC42C5 /* Precheckfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D55B28BF1F6C588300DC42C5 /* Precheckfile.swift */; };
|
||||
D55B28C71F6C588300DC42C5 /* Scanfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D55B28C01F6C588300DC42C5 /* Scanfile.swift */; };
|
||||
D55B28C81F6C588300DC42C5 /* Screengrabfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D55B28C11F6C588300DC42C5 /* Screengrabfile.swift */; };
|
||||
D55B28C91F6C588300DC42C5 /* Snapshotfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D55B28C21F6C588300DC42C5 /* Snapshotfile.swift */; };
|
||||
D5A7C48F1F7C4DAF00A91DE6 /* Appfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A7C48D1F7C4DAF00A91DE6 /* Appfile.swift */; };
|
||||
D5A7C4901F7C4DAF00A91DE6 /* Fastfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A7C48E1F7C4DAF00A91DE6 /* Fastfile.swift */; };
|
||||
D5B8A5B31FFDC49E00536B24 /* ControlCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5B8A5B21FFDC49D00536B24 /* ControlCommand.swift */; };
|
||||
D5BAFD121F7DAAFC0030B324 /* ArgumentProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5BAFD111F7DAAFC0030B324 /* ArgumentProcessor.swift */; };
|
||||
D5D1DE991FFEE8EA00502A00 /* RubyCommandable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5D1DE981FFEE8E900502A00 /* RubyCommandable.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
C0459CAB27261886002CDFB9 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "$SRCROOT/../..";
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
C0459CAC27261897002CDFB9 /* FastlaneRunner in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
0311E386230AC1B20060BB5C /* Plugins.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Plugins.swift; path = ../Plugins.swift; sourceTree = "<group>"; };
|
||||
0311E38A230AC9490060BB5C /* Actions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Actions.swift; path = ../Actions.swift; sourceTree = "<group>"; };
|
||||
1257253824B7992B00E04FA3 /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = main.swift; path = ../main.swift; sourceTree = "<group>"; };
|
||||
1267C3F32773A43E004DE48A /* Atomic.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Atomic.swift; path = ../Atomic.swift; sourceTree = "<group>"; };
|
||||
12D2EB8C2620D83B00844013 /* OptionalConfigValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = OptionalConfigValue.swift; path = ../OptionalConfigValue.swift; sourceTree = "<group>"; };
|
||||
B30206741F5E3E9000DE6EBD /* SnapshotfileProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SnapshotfileProtocol.swift; path = ../SnapshotfileProtocol.swift; sourceTree = "<group>"; };
|
||||
B30206751F5E3E9000DE6EBD /* GymfileProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GymfileProtocol.swift; path = ../GymfileProtocol.swift; sourceTree = "<group>"; };
|
||||
B30206761F5E3E9000DE6EBD /* MatchfileProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MatchfileProtocol.swift; path = ../MatchfileProtocol.swift; sourceTree = "<group>"; };
|
||||
B30206771F5E3E9000DE6EBD /* PrecheckfileProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PrecheckfileProtocol.swift; path = ../PrecheckfileProtocol.swift; sourceTree = "<group>"; };
|
||||
B30206781F5E3E9000DE6EBD /* ScanfileProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ScanfileProtocol.swift; path = ../ScanfileProtocol.swift; sourceTree = "<group>"; };
|
||||
B30206791F5E3E9000DE6EBD /* ScreengrabfileProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ScreengrabfileProtocol.swift; path = ../ScreengrabfileProtocol.swift; sourceTree = "<group>"; };
|
||||
B302067A1F5E3E9000DE6EBD /* DeliverfileProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DeliverfileProtocol.swift; path = ../DeliverfileProtocol.swift; sourceTree = "<group>"; };
|
||||
B3144C072005533400470AFE /* README.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.txt; sourceTree = "<group>"; };
|
||||
B3144C08200553C800470AFE /* README.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.txt; sourceTree = "<group>"; };
|
||||
B3144C09200553D400470AFE /* README.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.txt; sourceTree = "<group>"; };
|
||||
B3144C0A200553DC00470AFE /* README.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.txt; sourceTree = "<group>"; };
|
||||
B3BA659D1F5A269100B34850 /* Fastlane.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Fastlane.swift; path = ../Fastlane.swift; sourceTree = "<group>"; };
|
||||
B3BA659E1F5A269100B34850 /* LaneFileProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LaneFileProtocol.swift; path = ../LaneFileProtocol.swift; sourceTree = "<group>"; };
|
||||
B3BA65A01F5A269100B34850 /* RubyCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RubyCommand.swift; path = ../RubyCommand.swift; sourceTree = "<group>"; };
|
||||
B3BA65A11F5A269100B34850 /* Runner.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Runner.swift; path = ../Runner.swift; sourceTree = "<group>"; };
|
||||
B3BA65A21F5A269100B34850 /* SocketClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SocketClient.swift; path = ../SocketClient.swift; sourceTree = "<group>"; };
|
||||
B3BA65A31F5A269100B34850 /* SocketClientDelegateProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SocketClientDelegateProtocol.swift; path = ../SocketClientDelegateProtocol.swift; sourceTree = "<group>"; };
|
||||
B3BA65A41F5A269100B34850 /* SocketResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SocketResponse.swift; path = ../SocketResponse.swift; sourceTree = "<group>"; };
|
||||
B3BA65AE1F5A2D5C00B34850 /* RunnerArgument.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RunnerArgument.swift; path = ../RunnerArgument.swift; sourceTree = "<group>"; };
|
||||
D556D6A91F6A08F5003108E3 /* FastlaneRunner */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = FastlaneRunner; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D55B28BC1F6C588300DC42C5 /* Deliverfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Deliverfile.swift; path = ../Deliverfile.swift; sourceTree = "<group>"; };
|
||||
D55B28BD1F6C588300DC42C5 /* Gymfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Gymfile.swift; path = ../Gymfile.swift; sourceTree = "<group>"; };
|
||||
D55B28BE1F6C588300DC42C5 /* Matchfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Matchfile.swift; path = ../Matchfile.swift; sourceTree = "<group>"; };
|
||||
D55B28BF1F6C588300DC42C5 /* Precheckfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Precheckfile.swift; path = ../Precheckfile.swift; sourceTree = "<group>"; };
|
||||
D55B28C01F6C588300DC42C5 /* Scanfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Scanfile.swift; path = ../Scanfile.swift; sourceTree = "<group>"; };
|
||||
D55B28C11F6C588300DC42C5 /* Screengrabfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Screengrabfile.swift; path = ../Screengrabfile.swift; sourceTree = "<group>"; };
|
||||
D55B28C21F6C588300DC42C5 /* Snapshotfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Snapshotfile.swift; path = ../Snapshotfile.swift; sourceTree = "<group>"; };
|
||||
D5A7C48D1F7C4DAF00A91DE6 /* Appfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Appfile.swift; path = ../../Appfile.swift; sourceTree = "<group>"; };
|
||||
D5A7C48E1F7C4DAF00A91DE6 /* Fastfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Fastfile.swift; path = ../../Fastfile.swift; sourceTree = "<group>"; };
|
||||
D5B8A5B21FFDC49D00536B24 /* ControlCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ControlCommand.swift; path = ../ControlCommand.swift; sourceTree = "<group>"; };
|
||||
D5BAFD111F7DAAFC0030B324 /* ArgumentProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ArgumentProcessor.swift; path = ../ArgumentProcessor.swift; sourceTree = "<group>"; };
|
||||
D5D1DE981FFEE8E900502A00 /* RubyCommandable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RubyCommandable.swift; path = ../RubyCommandable.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
B33BAF541F51F8D90001A751 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
B33BAF4E1F51F8D90001A751 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B3BA65B01F5A324A00B34850 /* Fastlane Runner */,
|
||||
D556D6A91F6A08F5003108E3 /* FastlaneRunner */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B3BA65B01F5A324A00B34850 /* Fastlane Runner */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B3BA65B21F5A327B00B34850 /* Autogenerated API */,
|
||||
B3BA65B31F5A329800B34850 /* Fastfile Components */,
|
||||
B3BA65B11F5A325E00B34850 /* Networking */,
|
||||
D512BA011F7C7F40000D2137 /* Runner Code */,
|
||||
D5A7C48D1F7C4DAF00A91DE6 /* Appfile.swift */,
|
||||
D55B28BC1F6C588300DC42C5 /* Deliverfile.swift */,
|
||||
D5A7C48E1F7C4DAF00A91DE6 /* Fastfile.swift */,
|
||||
D55B28BD1F6C588300DC42C5 /* Gymfile.swift */,
|
||||
D55B28BE1F6C588300DC42C5 /* Matchfile.swift */,
|
||||
D55B28BF1F6C588300DC42C5 /* Precheckfile.swift */,
|
||||
D55B28C01F6C588300DC42C5 /* Scanfile.swift */,
|
||||
D55B28C11F6C588300DC42C5 /* Screengrabfile.swift */,
|
||||
D55B28C21F6C588300DC42C5 /* Snapshotfile.swift */,
|
||||
);
|
||||
name = "Fastlane Runner";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B3BA65B11F5A325E00B34850 /* Networking */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1267C3F32773A43E004DE48A /* Atomic.swift */,
|
||||
B3144C072005533400470AFE /* README.txt */,
|
||||
D5B8A5B21FFDC49D00536B24 /* ControlCommand.swift */,
|
||||
B3BA65A01F5A269100B34850 /* RubyCommand.swift */,
|
||||
D5D1DE981FFEE8E900502A00 /* RubyCommandable.swift */,
|
||||
B3BA65A11F5A269100B34850 /* Runner.swift */,
|
||||
B3BA65A21F5A269100B34850 /* SocketClient.swift */,
|
||||
B3BA65A31F5A269100B34850 /* SocketClientDelegateProtocol.swift */,
|
||||
B3BA65A41F5A269100B34850 /* SocketResponse.swift */,
|
||||
);
|
||||
name = Networking;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B3BA65B21F5A327B00B34850 /* Autogenerated API */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B3144C09200553D400470AFE /* README.txt */,
|
||||
0311E38A230AC9490060BB5C /* Actions.swift */,
|
||||
B3BA659D1F5A269100B34850 /* Fastlane.swift */,
|
||||
B302067A1F5E3E9000DE6EBD /* DeliverfileProtocol.swift */,
|
||||
B30206751F5E3E9000DE6EBD /* GymfileProtocol.swift */,
|
||||
B30206761F5E3E9000DE6EBD /* MatchfileProtocol.swift */,
|
||||
0311E386230AC1B20060BB5C /* Plugins.swift */,
|
||||
B30206771F5E3E9000DE6EBD /* PrecheckfileProtocol.swift */,
|
||||
B30206781F5E3E9000DE6EBD /* ScanfileProtocol.swift */,
|
||||
B30206791F5E3E9000DE6EBD /* ScreengrabfileProtocol.swift */,
|
||||
B30206741F5E3E9000DE6EBD /* SnapshotfileProtocol.swift */,
|
||||
);
|
||||
name = "Autogenerated API";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B3BA65B31F5A329800B34850 /* Fastfile Components */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B3144C08200553C800470AFE /* README.txt */,
|
||||
B3BA659E1F5A269100B34850 /* LaneFileProtocol.swift */,
|
||||
12D2EB8C2620D83B00844013 /* OptionalConfigValue.swift */,
|
||||
);
|
||||
name = "Fastfile Components";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D512BA011F7C7F40000D2137 /* Runner Code */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1257253824B7992B00E04FA3 /* main.swift */,
|
||||
B3144C0A200553DC00470AFE /* README.txt */,
|
||||
D5BAFD111F7DAAFC0030B324 /* ArgumentProcessor.swift */,
|
||||
B3BA65AE1F5A2D5C00B34850 /* RunnerArgument.swift */,
|
||||
);
|
||||
name = "Runner Code";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
B33BAF561F51F8D90001A751 /* FastlaneRunner */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = B33BAF5E1F51F8D90001A751 /* Build configuration list for PBXNativeTarget "FastlaneRunner" */;
|
||||
buildPhases = (
|
||||
B33BAF531F51F8D90001A751 /* Sources */,
|
||||
B33BAF541F51F8D90001A751 /* Frameworks */,
|
||||
C0459CAB27261886002CDFB9 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = FastlaneRunner;
|
||||
productName = FastlaneSwiftRunner;
|
||||
productReference = D556D6A91F6A08F5003108E3 /* FastlaneRunner */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
B33BAF4F1F51F8D90001A751 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0830;
|
||||
LastUpgradeCheck = 1300;
|
||||
ORGANIZATIONNAME = "Joshua Liebowitz";
|
||||
TargetAttributes = {
|
||||
B33BAF561F51F8D90001A751 = {
|
||||
CreatedOnToolsVersion = 8.3.3;
|
||||
LastSwiftMigration = 0900;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = B33BAF521F51F8D90001A751 /* Build configuration list for PBXProject "FastlaneSwiftRunner" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = B33BAF4E1F51F8D90001A751;
|
||||
productRefGroup = B33BAF4E1F51F8D90001A751;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
B33BAF561F51F8D90001A751 /* FastlaneRunner */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
B33BAF531F51F8D90001A751 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B3BA65A91F5A269100B34850 /* RubyCommand.swift in Sources */,
|
||||
D5D1DE991FFEE8EA00502A00 /* RubyCommandable.swift in Sources */,
|
||||
D55B28C41F6C588300DC42C5 /* Gymfile.swift in Sources */,
|
||||
B302067D1F5E3E9000DE6EBD /* MatchfileProtocol.swift in Sources */,
|
||||
1267C3F42773A43E004DE48A /* Atomic.swift in Sources */,
|
||||
B3BA65AC1F5A269100B34850 /* SocketClientDelegateProtocol.swift in Sources */,
|
||||
B3BA65A71F5A269100B34850 /* LaneFileProtocol.swift in Sources */,
|
||||
D55B28C61F6C588300DC42C5 /* Precheckfile.swift in Sources */,
|
||||
B302067F1F5E3E9000DE6EBD /* ScanfileProtocol.swift in Sources */,
|
||||
D55B28C51F6C588300DC42C5 /* Matchfile.swift in Sources */,
|
||||
B30206801F5E3E9000DE6EBD /* ScreengrabfileProtocol.swift in Sources */,
|
||||
D5BAFD121F7DAAFC0030B324 /* ArgumentProcessor.swift in Sources */,
|
||||
B302067C1F5E3E9000DE6EBD /* GymfileProtocol.swift in Sources */,
|
||||
B302067B1F5E3E9000DE6EBD /* SnapshotfileProtocol.swift in Sources */,
|
||||
D55B28C31F6C588300DC42C5 /* Deliverfile.swift in Sources */,
|
||||
D5A7C4901F7C4DAF00A91DE6 /* Fastfile.swift in Sources */,
|
||||
0311E38B230AC9490060BB5C /* Actions.swift in Sources */,
|
||||
D5A7C48F1F7C4DAF00A91DE6 /* Appfile.swift in Sources */,
|
||||
B3BA65AB1F5A269100B34850 /* SocketClient.swift in Sources */,
|
||||
B30206811F5E3E9000DE6EBD /* DeliverfileProtocol.swift in Sources */,
|
||||
B3BA65AA1F5A269100B34850 /* Runner.swift in Sources */,
|
||||
B3BA65AF1F5A2D5C00B34850 /* RunnerArgument.swift in Sources */,
|
||||
D5B8A5B31FFDC49E00536B24 /* ControlCommand.swift in Sources */,
|
||||
1257253924B7992C00E04FA3 /* main.swift in Sources */,
|
||||
B302067E1F5E3E9000DE6EBD /* PrecheckfileProtocol.swift in Sources */,
|
||||
B3BA65AD1F5A269100B34850 /* SocketResponse.swift in Sources */,
|
||||
D55B28C71F6C588300DC42C5 /* Scanfile.swift in Sources */,
|
||||
0311E387230AC1B20060BB5C /* Plugins.swift in Sources */,
|
||||
D55B28C91F6C588300DC42C5 /* Snapshotfile.swift in Sources */,
|
||||
B3BA65A61F5A269100B34850 /* Fastlane.swift in Sources */,
|
||||
D55B28C81F6C588300DC42C5 /* Screengrabfile.swift in Sources */,
|
||||
12D2EB8D2620D83C00844013 /* OptionalConfigValue.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
B33BAF5C1F51F8D90001A751 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.12;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
B33BAF5D1F51F8D90001A751 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.12;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = macosx;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
B33BAF5F1F51F8D90001A751 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
B33BAF601F51F8D90001A751 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
B33BAF521F51F8D90001A751 /* Build configuration list for PBXProject "FastlaneSwiftRunner" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
B33BAF5C1F51F8D90001A751 /* Debug */,
|
||||
B33BAF5D1F51F8D90001A751 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
B33BAF5E1F51F8D90001A751 /* Build configuration list for PBXNativeTarget "FastlaneRunner" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
B33BAF5F1F51F8D90001A751 /* Debug */,
|
||||
B33BAF601F51F8D90001A751 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = B33BAF4F1F51F8D90001A751 /* Project object */;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:FastlaneSwiftRunner.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
@ -0,0 +1,8 @@
|
||||
<?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>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1300"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "B33BAF561F51F8D90001A751"
|
||||
BuildableName = "FastlaneRunner"
|
||||
BlueprintName = "FastlaneRunner"
|
||||
ReferencedContainer = "container:FastlaneSwiftRunner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "B33BAF561F51F8D90001A751"
|
||||
BuildableName = "FastlaneRunner"
|
||||
BlueprintName = "FastlaneRunner"
|
||||
ReferencedContainer = "container:FastlaneSwiftRunner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "B33BAF561F51F8D90001A751"
|
||||
BuildableName = "FastlaneRunner"
|
||||
BlueprintName = "FastlaneRunner"
|
||||
ReferencedContainer = "container:FastlaneSwiftRunner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<CommandLineArguments>
|
||||
<CommandLineArgument
|
||||
argument = "lane testLane"
|
||||
isEnabled = "YES">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "logMode verbose"
|
||||
isEnabled = "YES">
|
||||
</CommandLineArgument>
|
||||
</CommandLineArguments>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "B33BAF561F51F8D90001A751"
|
||||
BuildableName = "FastlaneRunner"
|
||||
BlueprintName = "FastlaneRunner"
|
||||
ReferencedContainer = "container:FastlaneSwiftRunner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
10
fastlane/swift/FastlaneSwiftRunner/README.txt
Normal file
10
fastlane/swift/FastlaneSwiftRunner/README.txt
Normal file
@ -0,0 +1,10 @@
|
||||
Don't modify the structure of this group including but not limited to:
|
||||
- renaming this group
|
||||
- adding sub groups
|
||||
- removing sub groups
|
||||
- adding new files
|
||||
- removing files
|
||||
|
||||
If you modify anything in this folder, future fastlane upgrades may not be able to be applied automatically.
|
||||
|
||||
If you need to add new groups, please add them at the root of the "Fastlane Runner" group.
|
20
fastlane/swift/Gymfile.swift
Normal file
20
fastlane/swift/Gymfile.swift
Normal file
@ -0,0 +1,20 @@
|
||||
// Gymfile.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
// This class is automatically included in FastlaneRunner during build
|
||||
|
||||
// This autogenerated file will be overwritten or replaced during build time, or when you initialize `gym`
|
||||
//
|
||||
// ** 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
|
||||
//
|
||||
|
||||
public class Gymfile: GymfileProtocol {
|
||||
// If you want to enable `gym`, run `fastlane gym init`
|
||||
// After, this file will be replaced with a custom implementation that contains values you supplied
|
||||
// during the `init` process, and you won't see this message
|
||||
}
|
||||
|
||||
// Generated with fastlane 2.220.0
|
211
fastlane/swift/GymfileProtocol.swift
Normal file
211
fastlane/swift/GymfileProtocol.swift
Normal file
@ -0,0 +1,211 @@
|
||||
// GymfileProtocol.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
public protocol GymfileProtocol: AnyObject {
|
||||
/// Path to the workspace file
|
||||
var workspace: String? { get }
|
||||
|
||||
/// Path to the project file
|
||||
var project: String? { get }
|
||||
|
||||
/// The project's scheme. Make sure it's marked as `Shared`
|
||||
var scheme: String? { get }
|
||||
|
||||
/// Should the project be cleaned before building it?
|
||||
var clean: Bool { get }
|
||||
|
||||
/// The directory in which the ipa file should be stored in
|
||||
var outputDirectory: String { get }
|
||||
|
||||
/// The name of the resulting ipa file
|
||||
var outputName: String? { get }
|
||||
|
||||
/// The configuration to use when building the app. Defaults to 'Release'
|
||||
var configuration: String? { get }
|
||||
|
||||
/// Hide all information that's not necessary while building
|
||||
var silent: Bool { get }
|
||||
|
||||
/// The name of the code signing identity to use. It has to match the name exactly. e.g. 'iPhone Distribution: SunApps GmbH'
|
||||
var codesigningIdentity: String? { get }
|
||||
|
||||
/// Should we skip packaging the ipa?
|
||||
var skipPackageIpa: Bool { get }
|
||||
|
||||
/// Should we skip packaging the pkg?
|
||||
var skipPackagePkg: Bool { get }
|
||||
|
||||
/// Should the ipa file include symbols?
|
||||
var includeSymbols: Bool? { get }
|
||||
|
||||
/// Should the ipa file include bitcode?
|
||||
var includeBitcode: Bool? { get }
|
||||
|
||||
/// Method used to export the archive. Valid values are: app-store, validation, ad-hoc, package, enterprise, development, developer-id and mac-application
|
||||
var exportMethod: String? { get }
|
||||
|
||||
/// Path to an export options plist or a hash with export options. Use 'xcodebuild -help' to print the full set of available options
|
||||
var exportOptions: [String: Any]? { get }
|
||||
|
||||
/// Pass additional arguments to xcodebuild for the package phase. Be sure to quote the setting names and values e.g. OTHER_LDFLAGS="-ObjC -lstdc++"
|
||||
var exportXcargs: String? { get }
|
||||
|
||||
/// Export ipa from previously built xcarchive. Uses archive_path as source
|
||||
var skipBuildArchive: Bool? { get }
|
||||
|
||||
/// After building, don't archive, effectively not including -archivePath param
|
||||
var skipArchive: Bool? { get }
|
||||
|
||||
/// Build without codesigning
|
||||
var skipCodesigning: Bool? { get }
|
||||
|
||||
/// Platform to build when using a Catalyst enabled app. Valid values are: ios, macos
|
||||
var catalystPlatform: String? { get }
|
||||
|
||||
/// Full name of 3rd Party Mac Developer Installer or Developer ID Installer certificate. Example: `3rd Party Mac Developer Installer: Your Company (ABC1234XWYZ)`
|
||||
var installerCertName: String? { get }
|
||||
|
||||
/// The directory in which the archive should be stored in
|
||||
var buildPath: String? { get }
|
||||
|
||||
/// The path to the created archive
|
||||
var archivePath: String? { get }
|
||||
|
||||
/// The directory where built products and other derived data will go
|
||||
var derivedDataPath: String? { get }
|
||||
|
||||
/// Should an Xcode result bundle be generated in the output directory
|
||||
var resultBundle: Bool { get }
|
||||
|
||||
/// Path to the result bundle directory to create. Ignored if `result_bundle` if false
|
||||
var resultBundlePath: String? { get }
|
||||
|
||||
/// The directory where to store the build log
|
||||
var buildlogPath: String { get }
|
||||
|
||||
/// The SDK that should be used for building the application
|
||||
var sdk: String? { get }
|
||||
|
||||
/// The toolchain that should be used for building the application (e.g. com.apple.dt.toolchain.Swift_2_3, org.swift.30p620160816a)
|
||||
var toolchain: String? { get }
|
||||
|
||||
/// Use a custom destination for building the app
|
||||
var destination: String? { get }
|
||||
|
||||
/// Optional: Sometimes you need to specify a team id when exporting the ipa file
|
||||
var exportTeamId: String? { get }
|
||||
|
||||
/// Pass additional arguments to xcodebuild for the build phase. Be sure to quote the setting names and values e.g. OTHER_LDFLAGS="-ObjC -lstdc++"
|
||||
var xcargs: String? { get }
|
||||
|
||||
/// Use an extra XCCONFIG file to build your app
|
||||
var xcconfig: String? { get }
|
||||
|
||||
/// Suppress the output of xcodebuild to stdout. Output is still saved in buildlog_path
|
||||
var suppressXcodeOutput: Bool? { get }
|
||||
|
||||
/// xcodebuild formatter to use (ex: 'xcbeautify', 'xcbeautify --quieter', 'xcpretty', 'xcpretty -test'). Use empty string (ex: '') to disable any formatter (More information: https://docs.fastlane.tools/best-practices/xcodebuild-formatters/)
|
||||
var xcodebuildFormatter: String { get }
|
||||
|
||||
/// Create a build timing summary
|
||||
var buildTimingSummary: Bool { get }
|
||||
|
||||
/// **DEPRECATED!** Use `xcodebuild_formatter: ''` instead - Disable xcpretty formatting of build output
|
||||
var disableXcpretty: Bool? { get }
|
||||
|
||||
/// Use the test (RSpec style) format for build output
|
||||
var xcprettyTestFormat: Bool? { get }
|
||||
|
||||
/// A custom xcpretty formatter to use
|
||||
var xcprettyFormatter: String? { get }
|
||||
|
||||
/// Have xcpretty create a JUnit-style XML report at the provided path
|
||||
var xcprettyReportJunit: String? { get }
|
||||
|
||||
/// Have xcpretty create a simple HTML report at the provided path
|
||||
var xcprettyReportHtml: String? { get }
|
||||
|
||||
/// Have xcpretty create a JSON compilation database at the provided path
|
||||
var xcprettyReportJson: String? { get }
|
||||
|
||||
/// Have xcpretty use unicode encoding when reporting builds
|
||||
var xcprettyUtf: Bool? { get }
|
||||
|
||||
/// Analyze the project build time and store the output in 'culprits.txt' file
|
||||
var analyzeBuildTime: Bool? { get }
|
||||
|
||||
/// Do not try to build a profile mapping from the xcodeproj. Match or a manually provided mapping should be used
|
||||
var skipProfileDetection: Bool { get }
|
||||
|
||||
/// Allows for override of the default `xcodebuild` command
|
||||
var xcodebuildCommand: String { get }
|
||||
|
||||
/// Sets a custom path for Swift Package Manager dependencies
|
||||
var clonedSourcePackagesPath: String? { get }
|
||||
|
||||
/// Skips resolution of Swift Package Manager dependencies
|
||||
var skipPackageDependenciesResolution: Bool { get }
|
||||
|
||||
/// Prevents packages from automatically being resolved to versions other than those recorded in the `Package.resolved` file
|
||||
var disablePackageAutomaticUpdates: Bool { get }
|
||||
|
||||
/// Lets xcodebuild use system's scm configuration
|
||||
var useSystemScm: Bool { get }
|
||||
}
|
||||
|
||||
public extension GymfileProtocol {
|
||||
var workspace: String? { return nil }
|
||||
var project: String? { return nil }
|
||||
var scheme: String? { return nil }
|
||||
var clean: Bool { return false }
|
||||
var outputDirectory: String { return "." }
|
||||
var outputName: String? { return nil }
|
||||
var configuration: String? { return nil }
|
||||
var silent: Bool { return false }
|
||||
var codesigningIdentity: String? { return nil }
|
||||
var skipPackageIpa: Bool { return false }
|
||||
var skipPackagePkg: Bool { return false }
|
||||
var includeSymbols: Bool? { return nil }
|
||||
var includeBitcode: Bool? { return nil }
|
||||
var exportMethod: String? { return nil }
|
||||
var exportOptions: [String: Any]? { return nil }
|
||||
var exportXcargs: String? { return nil }
|
||||
var skipBuildArchive: Bool? { return nil }
|
||||
var skipArchive: Bool? { return nil }
|
||||
var skipCodesigning: Bool? { return nil }
|
||||
var catalystPlatform: String? { return nil }
|
||||
var installerCertName: String? { return nil }
|
||||
var buildPath: String? { return nil }
|
||||
var archivePath: String? { return nil }
|
||||
var derivedDataPath: String? { return nil }
|
||||
var resultBundle: Bool { return false }
|
||||
var resultBundlePath: String? { return nil }
|
||||
var buildlogPath: String { return "~/Library/Logs/gym" }
|
||||
var sdk: String? { return nil }
|
||||
var toolchain: String? { return nil }
|
||||
var destination: String? { return nil }
|
||||
var exportTeamId: String? { return nil }
|
||||
var xcargs: String? { return nil }
|
||||
var xcconfig: String? { return nil }
|
||||
var suppressXcodeOutput: Bool? { return nil }
|
||||
var xcodebuildFormatter: String { return "xcbeautify" }
|
||||
var buildTimingSummary: Bool { return false }
|
||||
var disableXcpretty: Bool? { return nil }
|
||||
var xcprettyTestFormat: Bool? { return nil }
|
||||
var xcprettyFormatter: String? { return nil }
|
||||
var xcprettyReportJunit: String? { return nil }
|
||||
var xcprettyReportHtml: String? { return nil }
|
||||
var xcprettyReportJson: String? { return nil }
|
||||
var xcprettyUtf: Bool? { return nil }
|
||||
var analyzeBuildTime: Bool? { return nil }
|
||||
var skipProfileDetection: Bool { return false }
|
||||
var xcodebuildCommand: String { return "xcodebuild" }
|
||||
var clonedSourcePackagesPath: String? { return nil }
|
||||
var skipPackageDependenciesResolution: Bool { return false }
|
||||
var disablePackageAutomaticUpdates: Bool { return false }
|
||||
var useSystemScm: Bool { return false }
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.127]
|
155
fastlane/swift/LaneFileProtocol.swift
Normal file
155
fastlane/swift/LaneFileProtocol.swift
Normal file
@ -0,0 +1,155 @@
|
||||
// LaneFileProtocol.swift
|
||||
// Copyright (c) 2024 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
|
||||
|
||||
public protocol LaneFileProtocol: AnyObject {
|
||||
var fastlaneVersion: String { get }
|
||||
static func runLane(from fastfile: LaneFile?, named lane: String, with parameters: [String: String]) -> Bool
|
||||
|
||||
func recordLaneDescriptions()
|
||||
func beforeAll(with lane: String)
|
||||
func afterAll(with lane: String)
|
||||
func onError(currentLane: String, errorInfo: String, errorClass: String?, errorMessage: String?)
|
||||
}
|
||||
|
||||
public extension LaneFileProtocol {
|
||||
var fastlaneVersion: String { return "" } // Defaults to "" because that means any is fine
|
||||
func beforeAll(with _: String) {} // No-op by default
|
||||
func afterAll(with _: String) {} // No-op by default
|
||||
func recordLaneDescriptions() {} // No-op by default
|
||||
}
|
||||
|
||||
@objcMembers
|
||||
open class LaneFile: NSObject, LaneFileProtocol {
|
||||
private(set) static var fastfileInstance: LaneFile?
|
||||
private static var onErrorCalled = Set<String>()
|
||||
|
||||
private static func trimLaneFromName(laneName: String) -> String {
|
||||
return String(laneName.prefix(laneName.count - 4))
|
||||
}
|
||||
|
||||
private static func trimLaneWithOptionsFromName(laneName: String) -> String {
|
||||
return String(laneName.prefix(laneName.count - 12))
|
||||
}
|
||||
|
||||
public func onError(currentLane: String, errorInfo _: String, errorClass _: String?, errorMessage _: String?) {
|
||||
LaneFile.onErrorCalled.insert(currentLane)
|
||||
}
|
||||
|
||||
private static var laneFunctionNames: [String] {
|
||||
var lanes: [String] = []
|
||||
var methodCount: UInt32 = 0
|
||||
#if !SWIFT_PACKAGE
|
||||
let methodList = class_copyMethodList(self, &methodCount)
|
||||
#else
|
||||
// In SPM we're calling this functions out of the scope of the normal binary that it's
|
||||
// being built, so *self* in this scope would be the SPM executable instead of the Fastfile
|
||||
// that we'd normally expect.
|
||||
let methodList = class_copyMethodList(type(of: fastfileInstance!), &methodCount)
|
||||
#endif
|
||||
for i in 0 ..< Int(methodCount) {
|
||||
let selName = sel_getName(method_getName(methodList![i]))
|
||||
let name = String(cString: selName)
|
||||
let lowercasedName = name.lowercased()
|
||||
if lowercasedName.hasSuffix("lane") || lowercasedName.hasSuffix("lanewithoptions:") {
|
||||
lanes.append(name)
|
||||
}
|
||||
}
|
||||
return lanes
|
||||
}
|
||||
|
||||
public static var lanes: [String: String] {
|
||||
var laneToMethodName: [String: String] = [:]
|
||||
for name in laneFunctionNames {
|
||||
let lowercasedName = name.lowercased()
|
||||
if lowercasedName.hasSuffix("lane") {
|
||||
laneToMethodName[lowercasedName] = name
|
||||
let lowercasedNameNoLane = trimLaneFromName(laneName: lowercasedName)
|
||||
laneToMethodName[lowercasedNameNoLane] = name
|
||||
} else if lowercasedName.hasSuffix("lanewithoptions:") {
|
||||
let lowercasedNameNoOptions = trimLaneWithOptionsFromName(laneName: lowercasedName)
|
||||
laneToMethodName[lowercasedNameNoOptions] = name
|
||||
let lowercasedNameNoLane = trimLaneFromName(laneName: lowercasedNameNoOptions)
|
||||
laneToMethodName[lowercasedNameNoLane] = name
|
||||
}
|
||||
}
|
||||
|
||||
return laneToMethodName
|
||||
}
|
||||
|
||||
public static func loadFastfile() {
|
||||
if fastfileInstance == nil {
|
||||
let fastfileType: AnyObject.Type = NSClassFromString(className())!
|
||||
let fastfileAsNSObjectType: NSObject.Type = fastfileType as! NSObject.Type
|
||||
let currentFastfileInstance: Fastfile? = fastfileAsNSObjectType.init() as? Fastfile
|
||||
fastfileInstance = currentFastfileInstance
|
||||
}
|
||||
}
|
||||
|
||||
public static func runLane(from fastfile: LaneFile?, named lane: String, with parameters: [String: String]) -> Bool {
|
||||
log(message: "Running lane: \(lane)")
|
||||
#if !SWIFT_PACKAGE
|
||||
// When not in SPM environment, we load the Fastfile from its `className()`.
|
||||
loadFastfile()
|
||||
guard let fastfileInstance = fastfileInstance as? Fastfile else {
|
||||
let message = "Unable to instantiate class named: \(className())"
|
||||
log(message: message)
|
||||
fatalError(message)
|
||||
}
|
||||
#else
|
||||
// When in SPM environment, we can't load the Fastfile from its `className()` because the executable is in
|
||||
// another scope, so `className()` won't be the expected Fastfile. Instead, we load the Fastfile as a Lanefile
|
||||
// in a static way, by parameter.
|
||||
guard let fastfileInstance = fastfile else {
|
||||
log(message: "Found nil instance of fastfile")
|
||||
preconditionFailure()
|
||||
}
|
||||
self.fastfileInstance = fastfileInstance
|
||||
#endif
|
||||
let currentLanes = lanes
|
||||
let lowerCasedLaneRequested = lane.lowercased()
|
||||
|
||||
guard let laneMethod = currentLanes[lowerCasedLaneRequested] else {
|
||||
let laneNames = laneFunctionNames.map { laneFunctionName in
|
||||
if laneFunctionName.hasSuffix("lanewithoptions:") {
|
||||
return trimLaneWithOptionsFromName(laneName: laneFunctionName)
|
||||
} else {
|
||||
return trimLaneFromName(laneName: laneFunctionName)
|
||||
}
|
||||
}.joined(separator: ", ")
|
||||
|
||||
let message = "[!] Could not find lane '\(lane)'. Available lanes: \(laneNames)"
|
||||
log(message: message)
|
||||
|
||||
let shutdownCommand = ControlCommand(commandType: .cancel(cancelReason: .clientError), message: message)
|
||||
_ = runner.executeCommand(shutdownCommand)
|
||||
return false
|
||||
}
|
||||
|
||||
// Call all methods that need to be called before we start calling lanes.
|
||||
fastfileInstance.beforeAll(with: lane)
|
||||
|
||||
// We need to catch all possible errors here and display a nice message.
|
||||
_ = fastfileInstance.perform(NSSelectorFromString(laneMethod), with: parameters)
|
||||
|
||||
// Call only on success.
|
||||
if !LaneFile.onErrorCalled.contains(lane) {
|
||||
fastfileInstance.afterAll(with: lane)
|
||||
}
|
||||
|
||||
log(message: "Done running lane: \(lane) 🚀")
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.2]
|
79
fastlane/swift/MainProcess.swift
Normal file
79
fastlane/swift/MainProcess.swift
Normal file
@ -0,0 +1,79 @@
|
||||
// MainProcess.swift
|
||||
// Copyright (c) 2024 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
|
||||
#if canImport(SwiftShell)
|
||||
import SwiftShell
|
||||
#endif
|
||||
|
||||
let argumentProcessor = ArgumentProcessor(args: CommandLine.arguments)
|
||||
let timeout = argumentProcessor.commandTimeout
|
||||
|
||||
class MainProcess {
|
||||
var doneRunningLane = false
|
||||
var thread: Thread!
|
||||
#if SWIFT_PACKAGE
|
||||
var lastPrintDate = Date.distantFuture
|
||||
var timeBetweenPrints = Int.min
|
||||
var rubySocketCommand: AsyncCommand!
|
||||
#endif
|
||||
|
||||
@objc func connectToFastlaneAndRunLane(_ fastfile: LaneFile?) {
|
||||
runner.startSocketThread(port: argumentProcessor.port)
|
||||
|
||||
let completedRun = Fastfile.runLane(from: fastfile, named: argumentProcessor.currentLane, with: argumentProcessor.laneParameters())
|
||||
if completedRun {
|
||||
runner.disconnectFromFastlaneProcess()
|
||||
}
|
||||
|
||||
doneRunningLane = true
|
||||
}
|
||||
|
||||
func startFastlaneThread(with fastFile: LaneFile?) {
|
||||
#if !SWIFT_PACKAGE
|
||||
thread = Thread(target: self, selector: #selector(connectToFastlaneAndRunLane), object: nil)
|
||||
#else
|
||||
thread = Thread(target: self, selector: #selector(connectToFastlaneAndRunLane), object: fastFile)
|
||||
#endif
|
||||
thread.name = "worker thread"
|
||||
#if SWIFT_PACKAGE
|
||||
let PATH = run("/bin/bash", "-c", "-l", "eval $(/usr/libexec/path_helper -s) ; echo $PATH").stdout
|
||||
main.env["PATH"] = PATH
|
||||
let path = main.run(bash: "which fastlane").stdout
|
||||
let pids = main.run("lsof", "-t", "-i", ":\(argumentProcessor.port)").stdout.split(separator: "\n")
|
||||
pids.forEach { main.run("kill", "-9", $0) }
|
||||
rubySocketCommand = main.runAsync(path, "socket_server", "-c", argumentProcessor.commandTimeout, "-p", argumentProcessor.port)
|
||||
lastPrintDate = Date()
|
||||
rubySocketCommand.stderror.onStringOutput { print($0) }
|
||||
rubySocketCommand.stdout.onStringOutput { stdout in
|
||||
print(stdout)
|
||||
self.timeBetweenPrints = Int(self.lastPrintDate.timeIntervalSinceNow)
|
||||
}
|
||||
|
||||
// swiftformat:disable:next redundantSelf
|
||||
_ = Runner.waitWithPolling(self.timeBetweenPrints, toEventually: { $0 > 5 }, timeout: 10)
|
||||
thread.start()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public class Main {
|
||||
let process = MainProcess()
|
||||
|
||||
public init() {}
|
||||
|
||||
public func run(with fastFile: LaneFile?) {
|
||||
process.startFastlaneThread(with: fastFile)
|
||||
|
||||
while !process.doneRunningLane, RunLoop.current.run(mode: RunLoopMode.defaultRunLoopMode, before: Date(timeIntervalSinceNow: 2)) {
|
||||
// no op
|
||||
}
|
||||
}
|
||||
}
|
20
fastlane/swift/Matchfile.swift
Normal file
20
fastlane/swift/Matchfile.swift
Normal file
@ -0,0 +1,20 @@
|
||||
// Matchfile.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
// This class is automatically included in FastlaneRunner during build
|
||||
|
||||
// This autogenerated file will be overwritten or replaced during build time, or when you initialize `match`
|
||||
//
|
||||
// ** 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
|
||||
//
|
||||
|
||||
public class Matchfile: MatchfileProtocol {
|
||||
// If you want to enable `match`, run `fastlane match init`
|
||||
// After, this file will be replaced with a custom implementation that contains values you supplied
|
||||
// during the `init` process, and you won't see this message
|
||||
}
|
||||
|
||||
// Generated with fastlane 2.220.0
|
231
fastlane/swift/MatchfileProtocol.swift
Normal file
231
fastlane/swift/MatchfileProtocol.swift
Normal file
@ -0,0 +1,231 @@
|
||||
// MatchfileProtocol.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
public protocol MatchfileProtocol: AnyObject {
|
||||
/// Define the profile type, can be appstore, adhoc, development, enterprise, developer_id, mac_installer_distribution, developer_id_installer
|
||||
var type: String { get }
|
||||
|
||||
/// Create additional cert types needed for macOS installers (valid values: mac_installer_distribution, developer_id_installer)
|
||||
var additionalCertTypes: [String]? { get }
|
||||
|
||||
/// Only fetch existing certificates and profiles, don't generate new ones
|
||||
var readonly: Bool { get }
|
||||
|
||||
/// Create a certificate type for Xcode 11 and later (Apple Development or Apple Distribution)
|
||||
var generateAppleCerts: Bool { get }
|
||||
|
||||
/// Skip syncing provisioning profiles
|
||||
var skipProvisioningProfiles: Bool { get }
|
||||
|
||||
/// The bundle identifier(s) of your app (comma-separated string or array of strings)
|
||||
var appIdentifier: [String] { get }
|
||||
|
||||
/// Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)
|
||||
var apiKeyPath: String? { get }
|
||||
|
||||
/// Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-hash-option)
|
||||
var apiKey: [String: Any]? { get }
|
||||
|
||||
/// Your Apple ID Username
|
||||
var username: String? { get }
|
||||
|
||||
/// The ID of your Developer Portal team if you're in multiple teams
|
||||
var teamId: String? { get }
|
||||
|
||||
/// The name of your Developer Portal team if you're in multiple teams
|
||||
var teamName: String? { get }
|
||||
|
||||
/// Define where you want to store your certificates
|
||||
var storageMode: String { get }
|
||||
|
||||
/// URL to the git repo containing all the certificates
|
||||
var gitUrl: String { get }
|
||||
|
||||
/// Specific git branch to use
|
||||
var gitBranch: String { get }
|
||||
|
||||
/// git user full name to commit
|
||||
var gitFullName: String? { get }
|
||||
|
||||
/// git user email to commit
|
||||
var gitUserEmail: String? { get }
|
||||
|
||||
/// Make a shallow clone of the repository (truncate the history to 1 revision)
|
||||
var shallowClone: Bool { get }
|
||||
|
||||
/// Clone just the branch specified, instead of the whole repo. This requires that the branch already exists. Otherwise the command will fail
|
||||
var cloneBranchDirectly: Bool { get }
|
||||
|
||||
/// Use a basic authorization header to access the git repo (e.g.: access via HTTPS, GitHub Actions, etc), usually a string in Base64
|
||||
var gitBasicAuthorization: String? { get }
|
||||
|
||||
/// Use a bearer authorization header to access the git repo (e.g.: access to an Azure DevOps repository), usually a string in Base64
|
||||
var gitBearerAuthorization: String? { get }
|
||||
|
||||
/// Use a private key to access the git repo (e.g.: access to GitHub repository via Deploy keys), usually a id_rsa named file or the contents hereof
|
||||
var gitPrivateKey: String? { get }
|
||||
|
||||
/// Name of the Google Cloud Storage bucket to use
|
||||
var googleCloudBucketName: String? { get }
|
||||
|
||||
/// Path to the gc_keys.json file
|
||||
var googleCloudKeysFile: String? { get }
|
||||
|
||||
/// ID of the Google Cloud project to use for authentication
|
||||
var googleCloudProjectId: String? { get }
|
||||
|
||||
/// Skips confirming to use the system google account
|
||||
var skipGoogleCloudAccountConfirmation: Bool { get }
|
||||
|
||||
/// Name of the S3 region
|
||||
var s3Region: String? { get }
|
||||
|
||||
/// S3 access key
|
||||
var s3AccessKey: String? { get }
|
||||
|
||||
/// S3 secret access key
|
||||
var s3SecretAccessKey: String? { get }
|
||||
|
||||
/// Name of the S3 bucket
|
||||
var s3Bucket: String? { get }
|
||||
|
||||
/// Prefix to be used on all objects uploaded to S3
|
||||
var s3ObjectPrefix: String? { get }
|
||||
|
||||
/// Skip encryption of all objects uploaded to S3. WARNING: only enable this on S3 buckets with sufficiently restricted permissions and server-side encryption enabled. See https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingEncryption.html
|
||||
var s3SkipEncryption: Bool { get }
|
||||
|
||||
/// GitLab Project Path (i.e. 'gitlab-org/gitlab')
|
||||
var gitlabProject: String? { get }
|
||||
|
||||
/// GitLab Host (i.e. 'https://gitlab.com')
|
||||
var gitlabHost: String { get }
|
||||
|
||||
/// GitLab CI_JOB_TOKEN
|
||||
var jobToken: String? { get }
|
||||
|
||||
/// GitLab Access Token
|
||||
var privateToken: String? { get }
|
||||
|
||||
/// Keychain the items should be imported to
|
||||
var keychainName: String { get }
|
||||
|
||||
/// This might be required the first time you access certificates on a new mac. For the login/default keychain this is your macOS account password
|
||||
var keychainPassword: String? { get }
|
||||
|
||||
/// Renew the provisioning profiles every time you run match
|
||||
var force: Bool { get }
|
||||
|
||||
/// Renew the provisioning profiles if the device count on the developer portal has changed. Ignored for profile types 'appstore' and 'developer_id'
|
||||
var forceForNewDevices: Bool { get }
|
||||
|
||||
/// Include Apple Silicon Mac devices in provisioning profiles for iOS/iPadOS apps
|
||||
var includeMacInProfiles: Bool { get }
|
||||
|
||||
/// Include all matching certificates in the provisioning profile. Works only for the 'development' provisioning profile type
|
||||
var includeAllCertificates: Bool { get }
|
||||
|
||||
/// Select certificate by id. Useful if multiple certificates are stored in one place
|
||||
var certificateId: String? { get }
|
||||
|
||||
/// Renew the provisioning profiles if the certificate count on the developer portal has changed. Works only for the 'development' provisioning profile type. Requires 'include_all_certificates' option to be 'true'
|
||||
var forceForNewCertificates: Bool { get }
|
||||
|
||||
/// Disables confirmation prompts during nuke, answering them with yes
|
||||
var skipConfirmation: Bool { get }
|
||||
|
||||
/// Remove certs from repository during nuke without revoking them on the developer portal
|
||||
var safeRemoveCerts: Bool { get }
|
||||
|
||||
/// Skip generation of a README.md for the created git repository
|
||||
var skipDocs: Bool { get }
|
||||
|
||||
/// Set the provisioning profile's platform to work with (i.e. ios, tvos, macos, catalyst)
|
||||
var platform: String { get }
|
||||
|
||||
/// Enable this if you have the Mac Catalyst capability enabled and your project was created with Xcode 11.3 or earlier. Prepends 'maccatalyst.' to the app identifier for the provisioning profile mapping
|
||||
var deriveCatalystAppIdentifier: Bool { get }
|
||||
|
||||
/// The name of provisioning profile template. If the developer account has provisioning profile templates (aka: custom entitlements), the template name can be found by inspecting the Entitlements drop-down while creating/editing a provisioning profile (e.g. "Apple Pay Pass Suppression Development")
|
||||
var templateName: String? { get }
|
||||
|
||||
/// A custom name for the provisioning profile. This will replace the default provisioning profile name if specified
|
||||
var profileName: String? { get }
|
||||
|
||||
/// Should the command fail if it was about to create a duplicate of an existing provisioning profile. It can happen due to issues on Apple Developer Portal, when profile to be recreated was not properly deleted first
|
||||
var failOnNameTaken: Bool { get }
|
||||
|
||||
/// Set to true if there is no access to Apple developer portal but there are certificates, keys and profiles provided. Only works with match import action
|
||||
var skipCertificateMatching: Bool { get }
|
||||
|
||||
/// Path in which to export certificates, key and profile
|
||||
var outputPath: String? { get }
|
||||
|
||||
/// Skips setting the partition list (which can sometimes take a long time). Setting the partition list is usually needed to prevent Xcode from prompting to allow a cert to be used for signing
|
||||
var skipSetPartitionList: Bool { get }
|
||||
|
||||
/// Print out extra information and all commands
|
||||
var verbose: Bool { get }
|
||||
}
|
||||
|
||||
public extension MatchfileProtocol {
|
||||
var type: String { return "development" }
|
||||
var additionalCertTypes: [String]? { return nil }
|
||||
var readonly: Bool { return false }
|
||||
var generateAppleCerts: Bool { return true }
|
||||
var skipProvisioningProfiles: Bool { return false }
|
||||
var appIdentifier: [String] { return [] }
|
||||
var apiKeyPath: String? { return nil }
|
||||
var apiKey: [String: Any]? { return nil }
|
||||
var username: String? { return nil }
|
||||
var teamId: String? { return nil }
|
||||
var teamName: String? { return nil }
|
||||
var storageMode: String { return "git" }
|
||||
var gitUrl: String { return "" }
|
||||
var gitBranch: String { return "master" }
|
||||
var gitFullName: String? { return nil }
|
||||
var gitUserEmail: String? { return nil }
|
||||
var shallowClone: Bool { return false }
|
||||
var cloneBranchDirectly: Bool { return false }
|
||||
var gitBasicAuthorization: String? { return nil }
|
||||
var gitBearerAuthorization: String? { return nil }
|
||||
var gitPrivateKey: String? { return nil }
|
||||
var googleCloudBucketName: String? { return nil }
|
||||
var googleCloudKeysFile: String? { return nil }
|
||||
var googleCloudProjectId: String? { return nil }
|
||||
var skipGoogleCloudAccountConfirmation: Bool { return false }
|
||||
var s3Region: String? { return nil }
|
||||
var s3AccessKey: String? { return nil }
|
||||
var s3SecretAccessKey: String? { return nil }
|
||||
var s3Bucket: String? { return nil }
|
||||
var s3ObjectPrefix: String? { return nil }
|
||||
var s3SkipEncryption: Bool { return false }
|
||||
var gitlabProject: String? { return nil }
|
||||
var gitlabHost: String { return "https://gitlab.com" }
|
||||
var jobToken: String? { return nil }
|
||||
var privateToken: String? { return nil }
|
||||
var keychainName: String { return "login.keychain" }
|
||||
var keychainPassword: String? { return nil }
|
||||
var force: Bool { return false }
|
||||
var forceForNewDevices: Bool { return false }
|
||||
var includeMacInProfiles: Bool { return false }
|
||||
var includeAllCertificates: Bool { return false }
|
||||
var certificateId: String? { return nil }
|
||||
var forceForNewCertificates: Bool { return false }
|
||||
var skipConfirmation: Bool { return false }
|
||||
var safeRemoveCerts: Bool { return false }
|
||||
var skipDocs: Bool { return false }
|
||||
var platform: String { return "ios" }
|
||||
var deriveCatalystAppIdentifier: Bool { return false }
|
||||
var templateName: String? { return nil }
|
||||
var profileName: String? { return nil }
|
||||
var failOnNameTaken: Bool { return false }
|
||||
var skipCertificateMatching: Bool { return false }
|
||||
var outputPath: String? { return nil }
|
||||
var skipSetPartitionList: Bool { return false }
|
||||
var verbose: Bool { return false }
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.121]
|
101
fastlane/swift/OptionalConfigValue.swift
Normal file
101
fastlane/swift/OptionalConfigValue.swift
Normal file
@ -0,0 +1,101 @@
|
||||
// OptionalConfigValue.swift
|
||||
// Copyright (c) 2024 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
|
||||
|
||||
public enum OptionalConfigValue<T> {
|
||||
case fastlaneDefault(T)
|
||||
case userDefined(T)
|
||||
case `nil`
|
||||
|
||||
func asRubyArgument(name: String, type: RubyCommand.Argument.ArgType? = nil) -> RubyCommand.Argument? {
|
||||
if case let .userDefined(value) = self {
|
||||
return RubyCommand.Argument(name: name, value: value, type: type)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
extension OptionalConfigValue: ExpressibleByUnicodeScalarLiteral where T == String? {
|
||||
public typealias UnicodeScalarLiteralType = String
|
||||
|
||||
public init(unicodeScalarLiteral value: UnicodeScalarLiteralType) {
|
||||
self = .userDefined(value)
|
||||
}
|
||||
}
|
||||
|
||||
extension OptionalConfigValue: ExpressibleByExtendedGraphemeClusterLiteral where T == String? {
|
||||
public typealias ExtendedGraphemeClusterLiteralType = String
|
||||
|
||||
public init(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterLiteralType) {
|
||||
self = .userDefined(value)
|
||||
}
|
||||
}
|
||||
|
||||
extension OptionalConfigValue: ExpressibleByStringLiteral where T == String? {
|
||||
public typealias StringLiteralType = String
|
||||
|
||||
public init(stringLiteral value: StringLiteralType) {
|
||||
self = .userDefined(value)
|
||||
}
|
||||
}
|
||||
|
||||
extension OptionalConfigValue: ExpressibleByStringInterpolation where T == String? {}
|
||||
|
||||
extension OptionalConfigValue: ExpressibleByNilLiteral {
|
||||
public init(nilLiteral _: ()) {
|
||||
self = .nil
|
||||
}
|
||||
}
|
||||
|
||||
extension OptionalConfigValue: ExpressibleByIntegerLiteral where T == Int? {
|
||||
public typealias IntegerLiteralType = Int
|
||||
|
||||
public init(integerLiteral value: IntegerLiteralType) {
|
||||
self = .userDefined(value)
|
||||
}
|
||||
}
|
||||
|
||||
extension OptionalConfigValue: ExpressibleByArrayLiteral where T == [String] {
|
||||
public typealias ArrayLiteralElement = String
|
||||
|
||||
public init(arrayLiteral elements: ArrayLiteralElement...) {
|
||||
self = .userDefined(elements)
|
||||
}
|
||||
}
|
||||
|
||||
extension OptionalConfigValue: ExpressibleByFloatLiteral where T == Float {
|
||||
public typealias FloatLiteralType = Float
|
||||
|
||||
public init(floatLiteral value: FloatLiteralType) {
|
||||
self = .userDefined(value)
|
||||
}
|
||||
}
|
||||
|
||||
extension OptionalConfigValue: ExpressibleByBooleanLiteral where T == Bool {
|
||||
public typealias BooleanLiteralType = Bool
|
||||
|
||||
public init(booleanLiteral value: BooleanLiteralType) {
|
||||
self = .userDefined(value)
|
||||
}
|
||||
}
|
||||
|
||||
extension OptionalConfigValue: ExpressibleByDictionaryLiteral where T == [String: Any] {
|
||||
public typealias Key = String
|
||||
public typealias Value = Any
|
||||
|
||||
public init(dictionaryLiteral elements: (Key, Value)...) {
|
||||
var dict: [Key: Value] = [:]
|
||||
for element in elements {
|
||||
dict[element.0] = element.1
|
||||
}
|
||||
self = .userDefined(dict)
|
||||
}
|
||||
}
|
16
fastlane/swift/Plugins.swift
Normal file
16
fastlane/swift/Plugins.swift
Normal file
@ -0,0 +1,16 @@
|
||||
// Plugins.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
// This autogenerated file will be overwritten or replaced when installing/updating plugins or running "fastlane generate_swift"
|
||||
//
|
||||
// ** 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
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.56]
|
20
fastlane/swift/Precheckfile.swift
Normal file
20
fastlane/swift/Precheckfile.swift
Normal file
@ -0,0 +1,20 @@
|
||||
// Precheckfile.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
// This class is automatically included in FastlaneRunner during build
|
||||
|
||||
// This autogenerated file will be overwritten or replaced during build time, or when you initialize `precheck`
|
||||
//
|
||||
// ** 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
|
||||
//
|
||||
|
||||
public class Precheckfile: PrecheckfileProtocol {
|
||||
// If you want to enable `precheck`, run `fastlane precheck init`
|
||||
// After, this file will be replaced with a custom implementation that contains values you supplied
|
||||
// during the `init` process, and you won't see this message
|
||||
}
|
||||
|
||||
// Generated with fastlane 2.220.0
|
55
fastlane/swift/PrecheckfileProtocol.swift
Normal file
55
fastlane/swift/PrecheckfileProtocol.swift
Normal file
@ -0,0 +1,55 @@
|
||||
// PrecheckfileProtocol.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
public protocol PrecheckfileProtocol: AnyObject {
|
||||
/// Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)
|
||||
var apiKeyPath: String? { get }
|
||||
|
||||
/// Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-hash-option)
|
||||
var apiKey: [String: Any]? { get }
|
||||
|
||||
/// The bundle identifier of your app
|
||||
var appIdentifier: String { get }
|
||||
|
||||
/// Your Apple ID Username
|
||||
var username: String? { get }
|
||||
|
||||
/// The ID of your App Store Connect team if you're in multiple teams
|
||||
var teamId: String? { get }
|
||||
|
||||
/// The name of your App Store Connect team if you're in multiple teams
|
||||
var teamName: String? { get }
|
||||
|
||||
/// The platform to use (optional)
|
||||
var platform: String { get }
|
||||
|
||||
/// The default rule level unless otherwise configured
|
||||
var defaultRuleLevel: String { get }
|
||||
|
||||
/// Should check in-app purchases?
|
||||
var includeInAppPurchases: Bool { get }
|
||||
|
||||
/// Should force check live app?
|
||||
var useLive: Bool { get }
|
||||
|
||||
/// using text indicating that your IAP is free
|
||||
var freeStuffInIap: String? { get }
|
||||
}
|
||||
|
||||
public extension PrecheckfileProtocol {
|
||||
var apiKeyPath: String? { return nil }
|
||||
var apiKey: [String: Any]? { return nil }
|
||||
var appIdentifier: String { return "" }
|
||||
var username: String? { return nil }
|
||||
var teamId: String? { return nil }
|
||||
var teamName: String? { return nil }
|
||||
var platform: String { return "ios" }
|
||||
var defaultRuleLevel: String { return "error" }
|
||||
var includeInAppPurchases: Bool { return true }
|
||||
var useLive: Bool { return false }
|
||||
var freeStuffInIap: String? { return nil }
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.120]
|
157
fastlane/swift/RubyCommand.swift
Normal file
157
fastlane/swift/RubyCommand.swift
Normal file
@ -0,0 +1,157 @@
|
||||
// RubyCommand.swift
|
||||
// Copyright (c) 2024 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]
|
43
fastlane/swift/RubyCommandable.swift
Normal file
43
fastlane/swift/RubyCommandable.swift
Normal file
@ -0,0 +1,43 @@
|
||||
// RubyCommandable.swift
|
||||
// Copyright (c) 2024 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
|
||||
|
||||
enum CommandType {
|
||||
case action
|
||||
case control
|
||||
|
||||
var token: String {
|
||||
switch self {
|
||||
case .action:
|
||||
return "action"
|
||||
case .control:
|
||||
return "control"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protocol RubyCommandable {
|
||||
var type: CommandType { get }
|
||||
var commandJson: String { get }
|
||||
var id: String { get }
|
||||
}
|
||||
|
||||
extension RubyCommandable {
|
||||
var json: String {
|
||||
return """
|
||||
{ "commandType": "\(type.token)", "command": \(commandJson) }
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.2]
|
279
fastlane/swift/Runner.swift
Normal file
279
fastlane/swift/Runner.swift
Normal file
@ -0,0 +1,279 @@
|
||||
// Runner.swift
|
||||
// Copyright (c) 2024 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
|
||||
|
||||
let logger: Logger = .init()
|
||||
|
||||
let runner: Runner = .init()
|
||||
|
||||
func desc(_: String) {
|
||||
// no-op, this is handled in fastlane/lane_list.rb
|
||||
}
|
||||
|
||||
class Runner {
|
||||
private var thread: Thread!
|
||||
private var socketClient: SocketClient!
|
||||
private let dispatchGroup = DispatchGroup()
|
||||
private var returnValue: String? // lol, so safe
|
||||
private var currentlyExecutingCommand: RubyCommandable?
|
||||
private var shouldLeaveDispatchGroupDuringDisconnect = false
|
||||
private var executeNext: AtomicDictionary<String, Bool> = {
|
||||
if #available(macOS 10.12, *) {
|
||||
return UnfairAtomicDictionary<String, Bool>()
|
||||
} else {
|
||||
return OSSPinAtomicDictionary<String, Bool>()
|
||||
}
|
||||
}()
|
||||
|
||||
func executeCommand(_ command: RubyCommandable) -> String {
|
||||
dispatchGroup.enter()
|
||||
currentlyExecutingCommand = command
|
||||
socketClient.send(rubyCommand: command)
|
||||
|
||||
let secondsToWait = DispatchTimeInterval.seconds(SocketClient.defaultCommandTimeoutSeconds)
|
||||
// swiftformat:disable:next redundantSelf
|
||||
let timeoutResult = Self.waitWithPolling(self.executeNext[command.id], toEventually: { $0 == true }, timeout: SocketClient.defaultCommandTimeoutSeconds)
|
||||
executeNext.removeValue(forKey: command.id)
|
||||
let failureMessage = "command didn't execute in: \(SocketClient.defaultCommandTimeoutSeconds) seconds"
|
||||
let success = testDispatchTimeoutResult(timeoutResult, failureMessage: failureMessage, timeToWait: secondsToWait)
|
||||
guard success else {
|
||||
log(message: "command timeout")
|
||||
preconditionFailure()
|
||||
}
|
||||
|
||||
if let _returnValue = returnValue {
|
||||
return _returnValue
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
static func waitWithPolling<T>(_ expression: @autoclosure @escaping () throws -> T, toEventually predicate: @escaping (T) -> Bool, timeout: Int, pollingInterval: DispatchTimeInterval = .milliseconds(4)) -> DispatchTimeoutResult {
|
||||
func memoizedClosure<T>(_ closure: @escaping () throws -> T) -> (Bool) throws -> T {
|
||||
var cache: T?
|
||||
return { withoutCaching in
|
||||
if withoutCaching || cache == nil {
|
||||
cache = try closure()
|
||||
}
|
||||
guard let cache = cache else {
|
||||
preconditionFailure()
|
||||
}
|
||||
|
||||
return cache
|
||||
}
|
||||
}
|
||||
|
||||
let runLoop = RunLoop.current
|
||||
let timeoutDate = Date(timeInterval: TimeInterval(timeout), since: Date())
|
||||
var fulfilled = false
|
||||
let _expression = memoizedClosure(expression)
|
||||
repeat {
|
||||
do {
|
||||
let exp = try _expression(true)
|
||||
fulfilled = predicate(exp)
|
||||
} catch {
|
||||
fatalError("Error raised \(error.localizedDescription)")
|
||||
}
|
||||
if !fulfilled {
|
||||
runLoop.run(until: Date(timeIntervalSinceNow: pollingInterval.timeInterval))
|
||||
} else {
|
||||
break
|
||||
}
|
||||
} while Date().compare(timeoutDate) == .orderedAscending
|
||||
|
||||
if fulfilled {
|
||||
return .success
|
||||
} else {
|
||||
return .timedOut
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle threading stuff
|
||||
extension Runner {
|
||||
func startSocketThread(port: UInt32) {
|
||||
let secondsToWait = DispatchTimeInterval.seconds(SocketClient.connectTimeoutSeconds)
|
||||
|
||||
dispatchGroup.enter()
|
||||
|
||||
socketClient = SocketClient(port: port, commandTimeoutSeconds: timeout, socketDelegate: self)
|
||||
thread = Thread(target: self, selector: #selector(startSocketComs), object: nil)
|
||||
guard let thread = thread else {
|
||||
preconditionFailure("Thread did not instantiate correctly")
|
||||
}
|
||||
|
||||
thread.name = "socket thread"
|
||||
thread.start()
|
||||
|
||||
let connectTimeout = DispatchTime.now() + secondsToWait
|
||||
let timeoutResult = dispatchGroup.wait(timeout: connectTimeout)
|
||||
|
||||
let failureMessage = "couldn't start socket thread in: \(SocketClient.connectTimeoutSeconds) seconds"
|
||||
let success = testDispatchTimeoutResult(timeoutResult, failureMessage: failureMessage, timeToWait: secondsToWait)
|
||||
guard success else {
|
||||
log(message: "socket thread timeout")
|
||||
preconditionFailure()
|
||||
}
|
||||
}
|
||||
|
||||
func disconnectFromFastlaneProcess() {
|
||||
shouldLeaveDispatchGroupDuringDisconnect = true
|
||||
dispatchGroup.enter()
|
||||
socketClient.sendComplete()
|
||||
|
||||
let connectTimeout = DispatchTime.now() + 2
|
||||
_ = dispatchGroup.wait(timeout: connectTimeout)
|
||||
}
|
||||
|
||||
@objc func startSocketComs() {
|
||||
guard let socketClient = socketClient else {
|
||||
return
|
||||
}
|
||||
|
||||
socketClient.connectAndOpenStreams()
|
||||
dispatchGroup.leave()
|
||||
}
|
||||
|
||||
private func testDispatchTimeoutResult(_ timeoutResult: DispatchTimeoutResult, failureMessage: String, timeToWait _: DispatchTimeInterval) -> Bool {
|
||||
switch timeoutResult {
|
||||
case .success:
|
||||
return true
|
||||
case .timedOut:
|
||||
log(message: "timeout: \(failureMessage)")
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Runner: SocketClientDelegateProtocol {
|
||||
func commandExecuted(serverResponse: SocketClientResponse, completion: (SocketClient) -> Void) {
|
||||
switch serverResponse {
|
||||
case let .success(returnedObject, closureArgumentValue):
|
||||
verbose(message: "command executed")
|
||||
returnValue = returnedObject
|
||||
if let command = currentlyExecutingCommand as? RubyCommand {
|
||||
if let closureArgumentValue = closureArgumentValue, !closureArgumentValue.isEmpty {
|
||||
command.performCallback(callbackArg: closureArgumentValue, socket: socketClient) {
|
||||
self.executeNext[command.id] = true
|
||||
}
|
||||
} else {
|
||||
executeNext[command.id] = true
|
||||
}
|
||||
}
|
||||
dispatchGroup.leave()
|
||||
completion(socketClient)
|
||||
case .clientInitiatedCancelAcknowledged:
|
||||
verbose(message: "server acknowledged a cancel request")
|
||||
dispatchGroup.leave()
|
||||
if let command = currentlyExecutingCommand as? RubyCommand {
|
||||
executeNext[command.id] = true
|
||||
}
|
||||
completion(socketClient)
|
||||
case .alreadyClosedSockets, .connectionFailure, .malformedRequest, .malformedResponse, .serverError:
|
||||
log(message: "error encountered while executing command:\n\(serverResponse)")
|
||||
dispatchGroup.leave()
|
||||
if let command = currentlyExecutingCommand as? RubyCommand {
|
||||
executeNext[command.id] = true
|
||||
}
|
||||
completion(socketClient)
|
||||
case let .commandTimeout(timeout):
|
||||
log(message: "Runner timed out after \(timeout) second(s)")
|
||||
}
|
||||
}
|
||||
|
||||
func connectionsOpened() {
|
||||
DispatchQueue.main.async {
|
||||
verbose(message: "connected!")
|
||||
}
|
||||
}
|
||||
|
||||
func connectionsClosed() {
|
||||
DispatchQueue.main.async {
|
||||
if let thread = self.thread {
|
||||
thread.cancel()
|
||||
}
|
||||
self.thread = nil
|
||||
self.socketClient.closeSession()
|
||||
self.socketClient = nil
|
||||
verbose(message: "connection closed!")
|
||||
if self.shouldLeaveDispatchGroupDuringDisconnect {
|
||||
self.dispatchGroup.leave()
|
||||
}
|
||||
exit(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Logger {
|
||||
enum LogMode {
|
||||
init(logMode: String) {
|
||||
switch logMode {
|
||||
case "normal", "default":
|
||||
self = .normal
|
||||
case "verbose":
|
||||
self = .verbose
|
||||
default:
|
||||
logger.log(message: "unrecognized log mode: \(logMode), defaulting to 'normal'")
|
||||
self = .normal
|
||||
}
|
||||
}
|
||||
|
||||
case normal
|
||||
case verbose
|
||||
}
|
||||
|
||||
public static var logMode: LogMode = .normal
|
||||
|
||||
func log(message: String) {
|
||||
let timestamp = NSDate().timeIntervalSince1970
|
||||
print("[\(timestamp)]: \(message)")
|
||||
}
|
||||
|
||||
func verbose(message: String) {
|
||||
if Logger.logMode == .verbose {
|
||||
let timestamp = NSDate().timeIntervalSince1970
|
||||
print("[\(timestamp)]: \(message)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func log(message: String) {
|
||||
logger.log(message: message)
|
||||
}
|
||||
|
||||
func verbose(message: String) {
|
||||
logger.verbose(message: message)
|
||||
}
|
||||
|
||||
private extension DispatchTimeInterval {
|
||||
var timeInterval: TimeInterval {
|
||||
var result: TimeInterval = 0
|
||||
switch self {
|
||||
case let .seconds(value):
|
||||
result = TimeInterval(value)
|
||||
case let .milliseconds(value):
|
||||
result = TimeInterval(value) * 0.001
|
||||
case let .microseconds(value):
|
||||
result = TimeInterval(value) * 0.000_001
|
||||
case let .nanoseconds(value):
|
||||
result = TimeInterval(value) * 0.000_000_001
|
||||
case .never:
|
||||
fatalError()
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.2]
|
20
fastlane/swift/RunnerArgument.swift
Normal file
20
fastlane/swift/RunnerArgument.swift
Normal file
@ -0,0 +1,20 @@
|
||||
// RunnerArgument.swift
|
||||
// Copyright (c) 2024 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 RunnerArgument {
|
||||
let name: String
|
||||
let value: String
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.2]
|
20
fastlane/swift/Scanfile.swift
Normal file
20
fastlane/swift/Scanfile.swift
Normal file
@ -0,0 +1,20 @@
|
||||
// Scanfile.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
// This class is automatically included in FastlaneRunner during build
|
||||
|
||||
// This autogenerated file will be overwritten or replaced during build time, or when you initialize `scan`
|
||||
//
|
||||
// ** 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
|
||||
//
|
||||
|
||||
public class Scanfile: ScanfileProtocol {
|
||||
// If you want to enable `scan`, run `fastlane scan init`
|
||||
// After, this file will be replaced with a custom implementation that contains values you supplied
|
||||
// during the `init` process, and you won't see this message
|
||||
}
|
||||
|
||||
// Generated with fastlane 2.220.0
|
323
fastlane/swift/ScanfileProtocol.swift
Normal file
323
fastlane/swift/ScanfileProtocol.swift
Normal file
@ -0,0 +1,323 @@
|
||||
// ScanfileProtocol.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
public protocol ScanfileProtocol: AnyObject {
|
||||
/// Path to the workspace file
|
||||
var workspace: String? { get }
|
||||
|
||||
/// Path to the project file
|
||||
var project: String? { get }
|
||||
|
||||
/// Path to the Swift Package
|
||||
var packagePath: String? { get }
|
||||
|
||||
/// The project's scheme. Make sure it's marked as `Shared`
|
||||
var scheme: String? { get }
|
||||
|
||||
/// The name of the simulator type you want to run tests on (e.g. 'iPhone 6' or 'iPhone SE (2nd generation) (14.5)')
|
||||
var device: String? { get }
|
||||
|
||||
/// Array of devices to run the tests on (e.g. ['iPhone 6', 'iPad Air', 'iPhone SE (2nd generation) (14.5)'])
|
||||
var devices: [String]? { get }
|
||||
|
||||
/// Should skip auto detecting of devices if none were specified
|
||||
var skipDetectDevices: Bool { get }
|
||||
|
||||
/// Should fail if devices not found
|
||||
var ensureDevicesFound: Bool { get }
|
||||
|
||||
/// Enabling this option will automatically killall Simulator processes before the run
|
||||
var forceQuitSimulator: Bool { get }
|
||||
|
||||
/// Enabling this option will automatically erase the simulator before running the application
|
||||
var resetSimulator: Bool { get }
|
||||
|
||||
/// Enabling this option will disable the simulator from showing the 'Slide to type' prompt
|
||||
var disableSlideToType: Bool { get }
|
||||
|
||||
/// Enabling this option will launch the first simulator prior to calling any xcodebuild command
|
||||
var prelaunchSimulator: Bool? { get }
|
||||
|
||||
/// Enabling this option will automatically uninstall the application before running it
|
||||
var reinstallApp: Bool { get }
|
||||
|
||||
/// The bundle identifier of the app to uninstall (only needed when enabling reinstall_app)
|
||||
var appIdentifier: String? { get }
|
||||
|
||||
/// Array of strings matching Test Bundle/Test Suite/Test Cases to run
|
||||
var onlyTesting: String? { get }
|
||||
|
||||
/// Array of strings matching Test Bundle/Test Suite/Test Cases to skip
|
||||
var skipTesting: String? { get }
|
||||
|
||||
/// The testplan associated with the scheme that should be used for testing
|
||||
var testplan: String? { get }
|
||||
|
||||
/// Array of strings matching test plan configurations to run
|
||||
var onlyTestConfigurations: String? { get }
|
||||
|
||||
/// Array of strings matching test plan configurations to skip
|
||||
var skipTestConfigurations: String? { get }
|
||||
|
||||
/// Run tests using the provided `.xctestrun` file
|
||||
var xctestrun: String? { get }
|
||||
|
||||
/// The toolchain that should be used for building the application (e.g. `com.apple.dt.toolchain.Swift_2_3, org.swift.30p620160816a`)
|
||||
var toolchain: String? { get }
|
||||
|
||||
/// Should the project be cleaned before building it?
|
||||
var clean: Bool { get }
|
||||
|
||||
/// Should code coverage be generated? (Xcode 7 and up)
|
||||
var codeCoverage: Bool? { get }
|
||||
|
||||
/// Should the address sanitizer be turned on?
|
||||
var addressSanitizer: Bool? { get }
|
||||
|
||||
/// Should the thread sanitizer be turned on?
|
||||
var threadSanitizer: Bool? { get }
|
||||
|
||||
/// Should the HTML report be opened when tests are completed?
|
||||
var openReport: Bool { get }
|
||||
|
||||
/// The directory in which all reports will be stored
|
||||
var outputDirectory: String { get }
|
||||
|
||||
/// Define how the output should look like. Valid values are: standard, basic, rspec, or raw (disables xcpretty during xcodebuild)
|
||||
var outputStyle: String? { get }
|
||||
|
||||
/// Comma separated list of the output types (e.g. html, junit, json-compilation-database)
|
||||
var outputTypes: String { get }
|
||||
|
||||
/// Comma separated list of the output files, corresponding to the types provided by :output_types (order should match). If specifying an output type of json-compilation-database with :use_clang_report_name enabled, that option will take precedence
|
||||
var outputFiles: String? { get }
|
||||
|
||||
/// The directory where to store the raw log
|
||||
var buildlogPath: String { get }
|
||||
|
||||
/// If the logs generated by the app (e.g. using NSLog, perror, etc.) in the Simulator should be written to the output_directory
|
||||
var includeSimulatorLogs: Bool { get }
|
||||
|
||||
/// Suppress the output of xcodebuild to stdout. Output is still saved in buildlog_path
|
||||
var suppressXcodeOutput: Bool? { get }
|
||||
|
||||
/// xcodebuild formatter to use (ex: 'xcbeautify', 'xcbeautify --quieter', 'xcpretty', 'xcpretty -test'). Use empty string (ex: '') to disable any formatter (More information: https://docs.fastlane.tools/best-practices/xcodebuild-formatters/)
|
||||
var xcodebuildFormatter: String { get }
|
||||
|
||||
/// Remove retry attempts from test results table and the JUnit report (if not using xcpretty)
|
||||
var outputRemoveRetryAttempts: Bool { get }
|
||||
|
||||
/// **DEPRECATED!** Use `output_style: 'raw'` instead - Disable xcpretty formatting of build, similar to `output_style='raw'` but this will also skip the test results table
|
||||
var disableXcpretty: Bool? { get }
|
||||
|
||||
/// **DEPRECATED!** Use 'xcpretty_formatter' instead - A custom xcpretty formatter to use
|
||||
var formatter: String? { get }
|
||||
|
||||
/// A custom xcpretty formatter to use
|
||||
var xcprettyFormatter: String? { get }
|
||||
|
||||
/// Pass in xcpretty additional command line arguments (e.g. '--test --no-color' or '--tap --no-utf')
|
||||
var xcprettyArgs: String? { get }
|
||||
|
||||
/// The directory where build products and other derived data will go
|
||||
var derivedDataPath: String? { get }
|
||||
|
||||
/// Should zip the derived data build products and place in output path?
|
||||
var shouldZipBuildProducts: Bool { get }
|
||||
|
||||
/// Should provide additional copy of .xctestrun file (settings.xctestrun) and place in output path?
|
||||
var outputXctestrun: Bool { get }
|
||||
|
||||
/// Custom path for the result bundle, overrides result_bundle
|
||||
var resultBundlePath: String? { get }
|
||||
|
||||
/// Should an Xcode result bundle be generated in the output directory
|
||||
var resultBundle: Bool { get }
|
||||
|
||||
/// Generate the json compilation database with clang naming convention (compile_commands.json)
|
||||
var useClangReportName: Bool { get }
|
||||
|
||||
/// Optionally override the per-target setting in the scheme for running tests in parallel. Equivalent to -parallel-testing-enabled
|
||||
var parallelTesting: Bool? { get }
|
||||
|
||||
/// Specify the exact number of test runners that will be spawned during parallel testing. Equivalent to -parallel-testing-worker-count
|
||||
var concurrentWorkers: Int? { get }
|
||||
|
||||
/// Constrain the number of simulator devices on which to test concurrently. Equivalent to -maximum-concurrent-test-simulator-destinations
|
||||
var maxConcurrentSimulators: Int? { get }
|
||||
|
||||
/// Do not run test bundles in parallel on the specified destinations. Testing will occur on each destination serially. Equivalent to -disable-concurrent-testing
|
||||
var disableConcurrentTesting: Bool { get }
|
||||
|
||||
/// Should debug build be skipped before test build?
|
||||
var skipBuild: Bool { get }
|
||||
|
||||
/// Test without building, requires a derived data path
|
||||
var testWithoutBuilding: Bool? { get }
|
||||
|
||||
/// Build for testing only, does not run tests
|
||||
var buildForTesting: Bool? { get }
|
||||
|
||||
/// The SDK that should be used for building the application
|
||||
var sdk: String? { get }
|
||||
|
||||
/// The configuration to use when building the app. Defaults to 'Release'
|
||||
var configuration: String? { get }
|
||||
|
||||
/// Pass additional arguments to xcodebuild. Be sure to quote the setting names and values e.g. OTHER_LDFLAGS="-ObjC -lstdc++"
|
||||
var xcargs: String? { get }
|
||||
|
||||
/// Use an extra XCCONFIG file to build your app
|
||||
var xcconfig: String? { get }
|
||||
|
||||
/// App name to use in slack message and logfile name
|
||||
var appName: String? { get }
|
||||
|
||||
/// Target version of the app being build or tested. Used to filter out simulator version
|
||||
var deploymentTargetVersion: String? { get }
|
||||
|
||||
/// Create an Incoming WebHook for your Slack group to post results there
|
||||
var slackUrl: String? { get }
|
||||
|
||||
/// #channel or @username
|
||||
var slackChannel: String? { get }
|
||||
|
||||
/// The message included with each message posted to slack
|
||||
var slackMessage: String? { get }
|
||||
|
||||
/// Use webhook's default username and icon settings? (true/false)
|
||||
var slackUseWebhookConfiguredUsernameAndIcon: Bool { get }
|
||||
|
||||
/// Overrides the webhook's username property if slack_use_webhook_configured_username_and_icon is false
|
||||
var slackUsername: String { get }
|
||||
|
||||
/// Overrides the webhook's image property if slack_use_webhook_configured_username_and_icon is false
|
||||
var slackIconUrl: String { get }
|
||||
|
||||
/// Don't publish to slack, even when an URL is given
|
||||
var skipSlack: Bool { get }
|
||||
|
||||
/// Only post on Slack if the tests fail
|
||||
var slackOnlyOnFailure: Bool { get }
|
||||
|
||||
/// Specifies default payloads to include in Slack messages. For more info visit https://docs.fastlane.tools/actions/slack
|
||||
var slackDefaultPayloads: [String]? { get }
|
||||
|
||||
/// Use only if you're a pro, use the other options instead
|
||||
var destination: String? { get }
|
||||
|
||||
/// Adds arch=x86_64 to the xcodebuild 'destination' argument to run simulator in a Rosetta mode
|
||||
var runRosettaSimulator: Bool { get }
|
||||
|
||||
/// Platform to build when using a Catalyst enabled app. Valid values are: ios, macos
|
||||
var catalystPlatform: String? { get }
|
||||
|
||||
/// **DEPRECATED!** Use `--output_files` instead - Sets custom full report file name when generating a single report
|
||||
var customReportFileName: String? { get }
|
||||
|
||||
/// Allows for override of the default `xcodebuild` command
|
||||
var xcodebuildCommand: String { get }
|
||||
|
||||
/// Sets a custom path for Swift Package Manager dependencies
|
||||
var clonedSourcePackagesPath: String? { get }
|
||||
|
||||
/// Skips resolution of Swift Package Manager dependencies
|
||||
var skipPackageDependenciesResolution: Bool { get }
|
||||
|
||||
/// Prevents packages from automatically being resolved to versions other than those recorded in the `Package.resolved` file
|
||||
var disablePackageAutomaticUpdates: Bool { get }
|
||||
|
||||
/// Lets xcodebuild use system's scm configuration
|
||||
var useSystemScm: Bool { get }
|
||||
|
||||
/// The number of times a test can fail
|
||||
var numberOfRetries: Int { get }
|
||||
|
||||
/// Should this step stop the build if the tests fail? Set this to false if you're using trainer
|
||||
var failBuild: Bool { get }
|
||||
}
|
||||
|
||||
public extension ScanfileProtocol {
|
||||
var workspace: String? { return nil }
|
||||
var project: String? { return nil }
|
||||
var packagePath: String? { return nil }
|
||||
var scheme: String? { return nil }
|
||||
var device: String? { return nil }
|
||||
var devices: [String]? { return nil }
|
||||
var skipDetectDevices: Bool { return false }
|
||||
var ensureDevicesFound: Bool { return false }
|
||||
var forceQuitSimulator: Bool { return false }
|
||||
var resetSimulator: Bool { return false }
|
||||
var disableSlideToType: Bool { return true }
|
||||
var prelaunchSimulator: Bool? { return nil }
|
||||
var reinstallApp: Bool { return false }
|
||||
var appIdentifier: String? { return nil }
|
||||
var onlyTesting: String? { return nil }
|
||||
var skipTesting: String? { return nil }
|
||||
var testplan: String? { return nil }
|
||||
var onlyTestConfigurations: String? { return nil }
|
||||
var skipTestConfigurations: String? { return nil }
|
||||
var xctestrun: String? { return nil }
|
||||
var toolchain: String? { return nil }
|
||||
var clean: Bool { return false }
|
||||
var codeCoverage: Bool? { return nil }
|
||||
var addressSanitizer: Bool? { return nil }
|
||||
var threadSanitizer: Bool? { return nil }
|
||||
var openReport: Bool { return false }
|
||||
var outputDirectory: String { return "./test_output" }
|
||||
var outputStyle: String? { return nil }
|
||||
var outputTypes: String { return "html,junit" }
|
||||
var outputFiles: String? { return nil }
|
||||
var buildlogPath: String { return "~/Library/Logs/scan" }
|
||||
var includeSimulatorLogs: Bool { return false }
|
||||
var suppressXcodeOutput: Bool? { return nil }
|
||||
var xcodebuildFormatter: String { return "xcbeautify" }
|
||||
var outputRemoveRetryAttempts: Bool { return false }
|
||||
var disableXcpretty: Bool? { return nil }
|
||||
var formatter: String? { return nil }
|
||||
var xcprettyFormatter: String? { return nil }
|
||||
var xcprettyArgs: String? { return nil }
|
||||
var derivedDataPath: String? { return nil }
|
||||
var shouldZipBuildProducts: Bool { return false }
|
||||
var outputXctestrun: Bool { return false }
|
||||
var resultBundlePath: String? { return nil }
|
||||
var resultBundle: Bool { return false }
|
||||
var useClangReportName: Bool { return false }
|
||||
var parallelTesting: Bool? { return nil }
|
||||
var concurrentWorkers: Int? { return nil }
|
||||
var maxConcurrentSimulators: Int? { return nil }
|
||||
var disableConcurrentTesting: Bool { return false }
|
||||
var skipBuild: Bool { return false }
|
||||
var testWithoutBuilding: Bool? { return nil }
|
||||
var buildForTesting: Bool? { return nil }
|
||||
var sdk: String? { return nil }
|
||||
var configuration: String? { return nil }
|
||||
var xcargs: String? { return nil }
|
||||
var xcconfig: String? { return nil }
|
||||
var appName: String? { return nil }
|
||||
var deploymentTargetVersion: String? { return nil }
|
||||
var slackUrl: String? { return nil }
|
||||
var slackChannel: String? { return nil }
|
||||
var slackMessage: String? { return nil }
|
||||
var slackUseWebhookConfiguredUsernameAndIcon: Bool { return false }
|
||||
var slackUsername: String { return "fastlane" }
|
||||
var slackIconUrl: String { return "https://fastlane.tools/assets/img/fastlane_icon.png" }
|
||||
var skipSlack: Bool { return false }
|
||||
var slackOnlyOnFailure: Bool { return false }
|
||||
var slackDefaultPayloads: [String]? { return nil }
|
||||
var destination: String? { return nil }
|
||||
var runRosettaSimulator: Bool { return false }
|
||||
var catalystPlatform: String? { return nil }
|
||||
var customReportFileName: String? { return nil }
|
||||
var xcodebuildCommand: String { return "env NSUnbufferedIO=YES xcodebuild" }
|
||||
var clonedSourcePackagesPath: String? { return nil }
|
||||
var skipPackageDependenciesResolution: Bool { return false }
|
||||
var disablePackageAutomaticUpdates: Bool { return false }
|
||||
var useSystemScm: Bool { return false }
|
||||
var numberOfRetries: Int { return 0 }
|
||||
var failBuild: Bool { return true }
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.132]
|
20
fastlane/swift/Screengrabfile.swift
Normal file
20
fastlane/swift/Screengrabfile.swift
Normal file
@ -0,0 +1,20 @@
|
||||
// Screengrabfile.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
// This class is automatically included in FastlaneRunner during build
|
||||
|
||||
// This autogenerated file will be overwritten or replaced during build time, or when you initialize `screengrab`
|
||||
//
|
||||
// ** 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
|
||||
//
|
||||
|
||||
public class Screengrabfile: ScreengrabfileProtocol {
|
||||
// If you want to enable `screengrab`, run `fastlane screengrab init`
|
||||
// After, this file will be replaced with a custom implementation that contains values you supplied
|
||||
// during the `init` process, and you won't see this message
|
||||
}
|
||||
|
||||
// Generated with fastlane 2.220.0
|
99
fastlane/swift/ScreengrabfileProtocol.swift
Normal file
99
fastlane/swift/ScreengrabfileProtocol.swift
Normal file
@ -0,0 +1,99 @@
|
||||
// ScreengrabfileProtocol.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
public protocol ScreengrabfileProtocol: AnyObject {
|
||||
/// Path to the root of your Android SDK installation, e.g. ~/tools/android-sdk-macosx
|
||||
var androidHome: String? { get }
|
||||
|
||||
/// **DEPRECATED!** The Android build tools version to use, e.g. '23.0.2'
|
||||
var buildToolsVersion: String? { get }
|
||||
|
||||
/// A list of locales which should be used
|
||||
var locales: [String] { get }
|
||||
|
||||
/// Enabling this option will automatically clear previously generated screenshots before running screengrab
|
||||
var clearPreviousScreenshots: Bool { get }
|
||||
|
||||
/// The directory where to store the screenshots
|
||||
var outputDirectory: String { get }
|
||||
|
||||
/// Don't open the summary after running _screengrab_
|
||||
var skipOpenSummary: Bool { get }
|
||||
|
||||
/// The package name of the app under test (e.g. com.yourcompany.yourapp)
|
||||
var appPackageName: String { get }
|
||||
|
||||
/// The package name of the tests bundle (e.g. com.yourcompany.yourapp.test)
|
||||
var testsPackageName: String? { get }
|
||||
|
||||
/// Only run tests in these Java packages
|
||||
var useTestsInPackages: [String]? { get }
|
||||
|
||||
/// Only run tests in these Java classes
|
||||
var useTestsInClasses: [String]? { get }
|
||||
|
||||
/// Additional launch arguments
|
||||
var launchArguments: [String]? { get }
|
||||
|
||||
/// The fully qualified class name of your test instrumentation runner
|
||||
var testInstrumentationRunner: String { get }
|
||||
|
||||
/// **DEPRECATED!** Return the device to this locale after running tests
|
||||
var endingLocale: String { get }
|
||||
|
||||
/// **DEPRECATED!** Restarts the adb daemon using `adb root` to allow access to screenshots directories on device. Use if getting 'Permission denied' errors
|
||||
var useAdbRoot: Bool { get }
|
||||
|
||||
/// The path to the APK for the app under test
|
||||
var appApkPath: String? { get }
|
||||
|
||||
/// The path to the APK for the tests bundle
|
||||
var testsApkPath: String? { get }
|
||||
|
||||
/// Use the device or emulator with the given serial number or qualifier
|
||||
var specificDevice: String? { get }
|
||||
|
||||
/// Type of device used for screenshots. Matches Google Play Types (phone, sevenInch, tenInch, tv, wear)
|
||||
var deviceType: String { get }
|
||||
|
||||
/// Whether or not to exit Screengrab on test failure. Exiting on failure will not copy screenshots to local machine nor open screenshots summary
|
||||
var exitOnTestFailure: Bool { get }
|
||||
|
||||
/// Enabling this option will automatically uninstall the application before running it
|
||||
var reinstallApp: Bool { get }
|
||||
|
||||
/// Add timestamp suffix to screenshot filename
|
||||
var useTimestampSuffix: Bool { get }
|
||||
|
||||
/// Configure the host used by adb to connect, allows running on remote devices farm
|
||||
var adbHost: String? { get }
|
||||
}
|
||||
|
||||
public extension ScreengrabfileProtocol {
|
||||
var androidHome: String? { return nil }
|
||||
var buildToolsVersion: String? { return nil }
|
||||
var locales: [String] { return ["en-US"] }
|
||||
var clearPreviousScreenshots: Bool { return false }
|
||||
var outputDirectory: String { return "fastlane/metadata/android" }
|
||||
var skipOpenSummary: Bool { return false }
|
||||
var appPackageName: String { return "" }
|
||||
var testsPackageName: String? { return nil }
|
||||
var useTestsInPackages: [String]? { return nil }
|
||||
var useTestsInClasses: [String]? { return nil }
|
||||
var launchArguments: [String]? { return nil }
|
||||
var testInstrumentationRunner: String { return "androidx.test.runner.AndroidJUnitRunner" }
|
||||
var endingLocale: String { return "en-US" }
|
||||
var useAdbRoot: Bool { return false }
|
||||
var appApkPath: String? { return nil }
|
||||
var testsApkPath: String? { return nil }
|
||||
var specificDevice: String? { return nil }
|
||||
var deviceType: String { return "phone" }
|
||||
var exitOnTestFailure: Bool { return true }
|
||||
var reinstallApp: Bool { return false }
|
||||
var useTimestampSuffix: Bool { return true }
|
||||
var adbHost: String? { return nil }
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.122]
|
20
fastlane/swift/Snapshotfile.swift
Normal file
20
fastlane/swift/Snapshotfile.swift
Normal file
@ -0,0 +1,20 @@
|
||||
// Snapshotfile.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
// This class is automatically included in FastlaneRunner during build
|
||||
|
||||
// This autogenerated file will be overwritten or replaced during build time, or when you initialize `snapshot`
|
||||
//
|
||||
// ** 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
|
||||
//
|
||||
|
||||
public class Snapshotfile: SnapshotfileProtocol {
|
||||
// If you want to enable `snapshot`, run `fastlane snapshot init`
|
||||
// After, this file will be replaced with a custom implementation that contains values you supplied
|
||||
// during the `init` process, and you won't see this message
|
||||
}
|
||||
|
||||
// Generated with fastlane 2.220.0
|
207
fastlane/swift/SnapshotfileProtocol.swift
Normal file
207
fastlane/swift/SnapshotfileProtocol.swift
Normal file
@ -0,0 +1,207 @@
|
||||
// SnapshotfileProtocol.swift
|
||||
// Copyright (c) 2024 FastlaneTools
|
||||
|
||||
public protocol SnapshotfileProtocol: AnyObject {
|
||||
/// Path to the workspace file
|
||||
var workspace: String? { get }
|
||||
|
||||
/// Path to the project file
|
||||
var project: String? { get }
|
||||
|
||||
/// Pass additional arguments to xcodebuild for the test phase. Be sure to quote the setting names and values e.g. OTHER_LDFLAGS="-ObjC -lstdc++"
|
||||
var xcargs: String? { get }
|
||||
|
||||
/// Use an extra XCCONFIG file to build your app
|
||||
var xcconfig: String? { get }
|
||||
|
||||
/// A list of devices you want to take the screenshots from
|
||||
var devices: [String]? { get }
|
||||
|
||||
/// A list of languages which should be used
|
||||
var languages: [String] { get }
|
||||
|
||||
/// A list of launch arguments which should be used
|
||||
var launchArguments: [String] { get }
|
||||
|
||||
/// The directory where to store the screenshots
|
||||
var outputDirectory: String { get }
|
||||
|
||||
/// If the logs generated by the app (e.g. using NSLog, perror, etc.) in the Simulator should be written to the output_directory
|
||||
var outputSimulatorLogs: Bool { get }
|
||||
|
||||
/// By default, the latest version should be used automatically. If you want to change it, do it here
|
||||
var iosVersion: String? { get }
|
||||
|
||||
/// Don't open the HTML summary after running _snapshot_
|
||||
var skipOpenSummary: Bool { get }
|
||||
|
||||
/// Do not check for most recent SnapshotHelper code
|
||||
var skipHelperVersionCheck: Bool { get }
|
||||
|
||||
/// Enabling this option will automatically clear previously generated screenshots before running snapshot
|
||||
var clearPreviousScreenshots: Bool { get }
|
||||
|
||||
/// Enabling this option will automatically uninstall the application before running it
|
||||
var reinstallApp: Bool { get }
|
||||
|
||||
/// Enabling this option will automatically erase the simulator before running the application
|
||||
var eraseSimulator: Bool { get }
|
||||
|
||||
/// Enabling this option will prevent displaying the simulator window
|
||||
var headless: Bool { get }
|
||||
|
||||
/// Enabling this option will automatically override the status bar to show 9:41 AM, full battery, and full reception (Adjust 'SNAPSHOT_SIMULATOR_WAIT_FOR_BOOT_TIMEOUT' environment variable if override status bar is not working. Might be because simulator is not fully booted. Defaults to 10 seconds)
|
||||
var overrideStatusBar: Bool { get }
|
||||
|
||||
/// Fully customize the status bar by setting each option here. Requires `override_status_bar` to be set to `true`. See `xcrun simctl status_bar --help`
|
||||
var overrideStatusBarArguments: String? { get }
|
||||
|
||||
/// Enabling this option will configure the Simulator's system language
|
||||
var localizeSimulator: Bool { get }
|
||||
|
||||
/// Enabling this option will configure the Simulator to be in dark mode (false for light, true for dark)
|
||||
var darkMode: Bool? { get }
|
||||
|
||||
/// The bundle identifier of the app to uninstall (only needed when enabling reinstall_app)
|
||||
var appIdentifier: String? { get }
|
||||
|
||||
/// A list of photos that should be added to the simulator before running the application
|
||||
var addPhotos: [String]? { get }
|
||||
|
||||
/// A list of videos that should be added to the simulator before running the application
|
||||
var addVideos: [String]? { get }
|
||||
|
||||
/// A path to screenshots.html template
|
||||
var htmlTemplate: String? { get }
|
||||
|
||||
/// The directory where to store the build log
|
||||
var buildlogPath: String { get }
|
||||
|
||||
/// Should the project be cleaned before building it?
|
||||
var clean: Bool { get }
|
||||
|
||||
/// Test without building, requires a derived data path
|
||||
var testWithoutBuilding: Bool? { get }
|
||||
|
||||
/// The configuration to use when building the app. Defaults to 'Release'
|
||||
var configuration: String? { get }
|
||||
|
||||
/// The SDK that should be used for building the application
|
||||
var sdk: String? { get }
|
||||
|
||||
/// The scheme you want to use, this must be the scheme for the UI Tests
|
||||
var scheme: String? { get }
|
||||
|
||||
/// The number of times a test can fail before snapshot should stop retrying
|
||||
var numberOfRetries: Int { get }
|
||||
|
||||
/// Should snapshot stop immediately after the tests completely failed on one device?
|
||||
var stopAfterFirstError: Bool { get }
|
||||
|
||||
/// The directory where build products and other derived data will go
|
||||
var derivedDataPath: String? { get }
|
||||
|
||||
/// Should an Xcode result bundle be generated in the output directory
|
||||
var resultBundle: Bool { get }
|
||||
|
||||
/// The name of the target you want to test (if you desire to override the Target Application from Xcode)
|
||||
var testTargetName: String? { get }
|
||||
|
||||
/// Separate the log files per device and per language
|
||||
var namespaceLogFiles: String? { get }
|
||||
|
||||
/// Take snapshots on multiple simulators concurrently. Note: This option is only applicable when running against Xcode 9
|
||||
var concurrentSimulators: Bool { get }
|
||||
|
||||
/// Disable the simulator from showing the 'Slide to type' prompt
|
||||
var disableSlideToType: Bool { get }
|
||||
|
||||
/// Sets a custom path for Swift Package Manager dependencies
|
||||
var clonedSourcePackagesPath: String? { get }
|
||||
|
||||
/// Skips resolution of Swift Package Manager dependencies
|
||||
var skipPackageDependenciesResolution: Bool { get }
|
||||
|
||||
/// Prevents packages from automatically being resolved to versions other than those recorded in the `Package.resolved` file
|
||||
var disablePackageAutomaticUpdates: Bool { get }
|
||||
|
||||
/// The testplan associated with the scheme that should be used for testing
|
||||
var testplan: String? { get }
|
||||
|
||||
/// Array of strings matching Test Bundle/Test Suite/Test Cases to run
|
||||
var onlyTesting: String? { get }
|
||||
|
||||
/// Array of strings matching Test Bundle/Test Suite/Test Cases to skip
|
||||
var skipTesting: String? { get }
|
||||
|
||||
/// xcodebuild formatter to use (ex: 'xcbeautify', 'xcbeautify --quieter', 'xcpretty', 'xcpretty -test'). Use empty string (ex: '') to disable any formatter (More information: https://docs.fastlane.tools/best-practices/xcodebuild-formatters/)
|
||||
var xcodebuildFormatter: String { get }
|
||||
|
||||
/// **DEPRECATED!** Use `xcodebuild_formatter: ''` instead - Additional xcpretty arguments
|
||||
var xcprettyArgs: String? { get }
|
||||
|
||||
/// Disable xcpretty formatting of build
|
||||
var disableXcpretty: Bool? { get }
|
||||
|
||||
/// Suppress the output of xcodebuild to stdout. Output is still saved in buildlog_path
|
||||
var suppressXcodeOutput: Bool? { get }
|
||||
|
||||
/// Lets xcodebuild use system's scm configuration
|
||||
var useSystemScm: Bool { get }
|
||||
}
|
||||
|
||||
public extension SnapshotfileProtocol {
|
||||
var workspace: String? { return nil }
|
||||
var project: String? { return nil }
|
||||
var xcargs: String? { return nil }
|
||||
var xcconfig: String? { return nil }
|
||||
var devices: [String]? { return nil }
|
||||
var languages: [String] { return ["en-US"] }
|
||||
var launchArguments: [String] { return [""] }
|
||||
var outputDirectory: String { return "screenshots" }
|
||||
var outputSimulatorLogs: Bool { return false }
|
||||
var iosVersion: String? { return nil }
|
||||
var skipOpenSummary: Bool { return false }
|
||||
var skipHelperVersionCheck: Bool { return false }
|
||||
var clearPreviousScreenshots: Bool { return false }
|
||||
var reinstallApp: Bool { return false }
|
||||
var eraseSimulator: Bool { return false }
|
||||
var headless: Bool { return true }
|
||||
var overrideStatusBar: Bool { return false }
|
||||
var overrideStatusBarArguments: String? { return nil }
|
||||
var localizeSimulator: Bool { return false }
|
||||
var darkMode: Bool? { return nil }
|
||||
var appIdentifier: String? { return nil }
|
||||
var addPhotos: [String]? { return nil }
|
||||
var addVideos: [String]? { return nil }
|
||||
var htmlTemplate: String? { return nil }
|
||||
var buildlogPath: String { return "~/Library/Logs/snapshot" }
|
||||
var clean: Bool { return false }
|
||||
var testWithoutBuilding: Bool? { return nil }
|
||||
var configuration: String? { return nil }
|
||||
var sdk: String? { return nil }
|
||||
var scheme: String? { return nil }
|
||||
var numberOfRetries: Int { return 1 }
|
||||
var stopAfterFirstError: Bool { return false }
|
||||
var derivedDataPath: String? { return nil }
|
||||
var resultBundle: Bool { return false }
|
||||
var testTargetName: String? { return nil }
|
||||
var namespaceLogFiles: String? { return nil }
|
||||
var concurrentSimulators: Bool { return true }
|
||||
var disableSlideToType: Bool { return false }
|
||||
var clonedSourcePackagesPath: String? { return nil }
|
||||
var skipPackageDependenciesResolution: Bool { return false }
|
||||
var disablePackageAutomaticUpdates: Bool { return false }
|
||||
var testplan: String? { return nil }
|
||||
var onlyTesting: String? { return nil }
|
||||
var skipTesting: String? { return nil }
|
||||
var xcodebuildFormatter: String { return "xcbeautify" }
|
||||
var xcprettyArgs: String? { return nil }
|
||||
var disableXcpretty: Bool? { return nil }
|
||||
var suppressXcodeOutput: Bool? { return nil }
|
||||
var useSystemScm: Bool { return false }
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.116]
|
332
fastlane/swift/SocketClient.swift
Normal file
332
fastlane/swift/SocketClient.swift
Normal file
@ -0,0 +1,332 @@
|
||||
// SocketClient.swift
|
||||
// Copyright (c) 2024 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 Dispatch
|
||||
import Foundation
|
||||
|
||||
public enum SocketClientResponse: Error {
|
||||
case alreadyClosedSockets
|
||||
case malformedRequest
|
||||
case malformedResponse
|
||||
case serverError
|
||||
case clientInitiatedCancelAcknowledged
|
||||
case commandTimeout(seconds: Int)
|
||||
case connectionFailure
|
||||
case success(returnedObject: String?, closureArgumentValue: String?)
|
||||
}
|
||||
|
||||
class SocketClient: NSObject {
|
||||
enum SocketStatus {
|
||||
case ready
|
||||
case closed
|
||||
}
|
||||
|
||||
static let connectTimeoutSeconds = 2
|
||||
static let defaultCommandTimeoutSeconds = 10800 // 3 hours
|
||||
static let doneToken = "done" // TODO: remove these
|
||||
static let cancelToken = "cancelFastlaneRun"
|
||||
|
||||
fileprivate var inputStream: InputStream!
|
||||
fileprivate var outputStream: OutputStream!
|
||||
fileprivate var cleaningUpAfterDone = false
|
||||
fileprivate let dispatchGroup = DispatchGroup()
|
||||
fileprivate let readSemaphore = DispatchSemaphore(value: 1)
|
||||
fileprivate let writeSemaphore = DispatchSemaphore(value: 1)
|
||||
fileprivate let commandTimeoutSeconds: Int
|
||||
|
||||
private let writeQueue: DispatchQueue
|
||||
private let readQueue: DispatchQueue
|
||||
private let streamQueue: DispatchQueue
|
||||
private let host: String
|
||||
private let port: UInt32
|
||||
|
||||
let maxReadLength = 65536 // max for ipc on 10.12 is kern.ipc.maxsockbuf: 8388608 ($sysctl kern.ipc.maxsockbuf)
|
||||
|
||||
private(set) weak var socketDelegate: SocketClientDelegateProtocol?
|
||||
|
||||
public private(set) var socketStatus: SocketStatus
|
||||
|
||||
// localhost only, this prevents other computers from connecting
|
||||
init(host: String = "localhost", port: UInt32 = 2000, commandTimeoutSeconds: Int = defaultCommandTimeoutSeconds, socketDelegate: SocketClientDelegateProtocol) {
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.commandTimeoutSeconds = commandTimeoutSeconds
|
||||
readQueue = DispatchQueue(label: "readQueue", qos: .background, attributes: .concurrent)
|
||||
writeQueue = DispatchQueue(label: "writeQueue", qos: .background, attributes: .concurrent)
|
||||
streamQueue = DispatchQueue.global(qos: .background)
|
||||
socketStatus = .closed
|
||||
self.socketDelegate = socketDelegate
|
||||
super.init()
|
||||
}
|
||||
|
||||
func connectAndOpenStreams() {
|
||||
var readStream: Unmanaged<CFReadStream>?
|
||||
var writeStream: Unmanaged<CFWriteStream>?
|
||||
|
||||
streamQueue.sync {
|
||||
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, self.host as CFString, self.port, &readStream, &writeStream)
|
||||
|
||||
self.inputStream = readStream!.takeRetainedValue()
|
||||
self.outputStream = writeStream!.takeRetainedValue()
|
||||
|
||||
self.inputStream.delegate = self
|
||||
self.outputStream.delegate = self
|
||||
|
||||
self.inputStream.schedule(in: .main, forMode: .defaultRunLoopMode)
|
||||
self.outputStream.schedule(in: .main, forMode: .defaultRunLoopMode)
|
||||
}
|
||||
|
||||
dispatchGroup.enter()
|
||||
readQueue.sync {
|
||||
self.inputStream.open()
|
||||
}
|
||||
|
||||
dispatchGroup.enter()
|
||||
writeQueue.sync {
|
||||
self.outputStream.open()
|
||||
}
|
||||
|
||||
let secondsToWait = DispatchTimeInterval.seconds(SocketClient.connectTimeoutSeconds)
|
||||
let connectTimeout = DispatchTime.now() + secondsToWait
|
||||
|
||||
let timeoutResult = dispatchGroup.wait(timeout: connectTimeout)
|
||||
let failureMessage = "Couldn't connect to ruby process within: \(SocketClient.connectTimeoutSeconds) seconds"
|
||||
|
||||
let success = testDispatchTimeoutResult(timeoutResult, failureMessage: failureMessage, timeToWait: secondsToWait)
|
||||
|
||||
guard success else {
|
||||
socketDelegate?.commandExecuted(serverResponse: .connectionFailure) { _ in }
|
||||
return
|
||||
}
|
||||
|
||||
socketStatus = .ready
|
||||
socketDelegate?.connectionsOpened()
|
||||
}
|
||||
|
||||
public func send(rubyCommand: RubyCommandable) {
|
||||
verbose(message: "sending: \(rubyCommand.json)")
|
||||
send(string: rubyCommand.json)
|
||||
writeSemaphore.signal()
|
||||
}
|
||||
|
||||
public func sendComplete() {
|
||||
closeSession(sendAbort: true)
|
||||
}
|
||||
|
||||
private func testDispatchTimeoutResult(_ timeoutResult: DispatchTimeoutResult, failureMessage: String, timeToWait: DispatchTimeInterval) -> Bool {
|
||||
switch timeoutResult {
|
||||
case .success:
|
||||
return true
|
||||
case .timedOut:
|
||||
log(message: "Timeout: \(failureMessage)")
|
||||
|
||||
if case let .seconds(seconds) = timeToWait {
|
||||
socketDelegate?.commandExecuted(serverResponse: .commandTimeout(seconds: seconds)) { _ in }
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private func stopInputSession() {
|
||||
inputStream.close()
|
||||
}
|
||||
|
||||
private func stopOutputSession() {
|
||||
outputStream.close()
|
||||
}
|
||||
|
||||
private func sendThroughQueue(string: String) {
|
||||
let data = string.data(using: .utf8)!
|
||||
data.withUnsafeBytes { (buffer: UnsafeRawBufferPointer) in
|
||||
if let buffer = buffer.baseAddress {
|
||||
self.outputStream.write(buffer.assumingMemoryBound(to: UInt8.self), maxLength: data.count)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func privateSend(string: String) {
|
||||
writeQueue.sync {
|
||||
writeSemaphore.wait()
|
||||
self.sendThroughQueue(string: string)
|
||||
writeSemaphore.signal()
|
||||
let timeoutSeconds = self.cleaningUpAfterDone ? 1 : self.commandTimeoutSeconds
|
||||
let timeToWait = DispatchTimeInterval.seconds(timeoutSeconds)
|
||||
let commandTimeout = DispatchTime.now() + timeToWait
|
||||
let timeoutResult = writeSemaphore.wait(timeout: commandTimeout)
|
||||
|
||||
_ = self.testDispatchTimeoutResult(timeoutResult, failureMessage: "Ruby process didn't return after: \(SocketClient.connectTimeoutSeconds) seconds", timeToWait: timeToWait)
|
||||
}
|
||||
}
|
||||
|
||||
private func send(string: String) {
|
||||
guard !cleaningUpAfterDone else {
|
||||
// This will happen after we abort if there are commands waiting to be executed
|
||||
// Need to check state of SocketClient in command runner to make sure we can accept `send`
|
||||
socketDelegate?.commandExecuted(serverResponse: .alreadyClosedSockets) { _ in }
|
||||
return
|
||||
}
|
||||
|
||||
if string == SocketClient.doneToken {
|
||||
cleaningUpAfterDone = true
|
||||
}
|
||||
|
||||
privateSend(string: string)
|
||||
}
|
||||
|
||||
func closeSession(sendAbort: Bool = true) {
|
||||
socketStatus = .closed
|
||||
|
||||
stopInputSession()
|
||||
|
||||
if sendAbort {
|
||||
send(rubyCommand: ControlCommand(commandType: .done))
|
||||
}
|
||||
|
||||
stopOutputSession()
|
||||
socketDelegate?.connectionsClosed()
|
||||
}
|
||||
|
||||
public func enter() {
|
||||
dispatchGroup.enter()
|
||||
}
|
||||
|
||||
public func leave() {
|
||||
readSemaphore.signal()
|
||||
writeSemaphore.signal()
|
||||
}
|
||||
}
|
||||
|
||||
extension SocketClient: StreamDelegate {
|
||||
func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
|
||||
guard !cleaningUpAfterDone else {
|
||||
// Still getting response from server even though we are done.
|
||||
// No big deal, we're closing the streams anyway.
|
||||
// That being said, we need to balance out the dispatchGroups
|
||||
dispatchGroup.leave()
|
||||
return
|
||||
}
|
||||
|
||||
if aStream === inputStream {
|
||||
switch eventCode {
|
||||
case Stream.Event.openCompleted:
|
||||
dispatchGroup.leave()
|
||||
|
||||
case Stream.Event.errorOccurred:
|
||||
verbose(message: "input stream error occurred")
|
||||
closeSession(sendAbort: true)
|
||||
|
||||
case Stream.Event.hasBytesAvailable:
|
||||
read()
|
||||
|
||||
case Stream.Event.endEncountered:
|
||||
// nothing special here
|
||||
break
|
||||
|
||||
case Stream.Event.hasSpaceAvailable:
|
||||
// we don't care about this
|
||||
break
|
||||
|
||||
default:
|
||||
verbose(message: "input stream caused unrecognized event: \(eventCode)")
|
||||
}
|
||||
|
||||
} else if aStream === outputStream {
|
||||
switch eventCode {
|
||||
case Stream.Event.openCompleted:
|
||||
dispatchGroup.leave()
|
||||
|
||||
case Stream.Event.errorOccurred:
|
||||
// probably safe to close all the things because Ruby already disconnected
|
||||
verbose(message: "output stream received error")
|
||||
|
||||
case Stream.Event.endEncountered:
|
||||
// nothing special here
|
||||
break
|
||||
|
||||
case Stream.Event.hasSpaceAvailable:
|
||||
// we don't care about this
|
||||
break
|
||||
|
||||
default:
|
||||
verbose(message: "output stream caused unrecognized event: \(eventCode)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func read() {
|
||||
readQueue.sync {
|
||||
self.readSemaphore.wait()
|
||||
var buffer = [UInt8](repeating: 0, count: maxReadLength)
|
||||
var output = ""
|
||||
while self.inputStream!.hasBytesAvailable {
|
||||
let bytesRead: Int = inputStream!.read(&buffer, maxLength: buffer.count)
|
||||
if bytesRead >= 0 {
|
||||
guard let read = String(bytes: buffer[..<bytesRead], encoding: .utf8) else {
|
||||
fatalError("Unable to decode bytes from buffer \(buffer[..<bytesRead])")
|
||||
}
|
||||
output.append(contentsOf: read)
|
||||
} else {
|
||||
verbose(message: "Stream read() error")
|
||||
}
|
||||
}
|
||||
self.processResponse(string: output)
|
||||
readSemaphore.signal()
|
||||
}
|
||||
}
|
||||
|
||||
func handleFailure(message: [String]) {
|
||||
log(message: "Encountered a problem: \(message.joined(separator: "\n"))")
|
||||
let shutdownCommand = ControlCommand(commandType: .cancel(cancelReason: .serverError))
|
||||
send(rubyCommand: shutdownCommand)
|
||||
}
|
||||
|
||||
func processResponse(string: String) {
|
||||
guard !string.isEmpty else {
|
||||
socketDelegate?.commandExecuted(serverResponse: .malformedResponse) {
|
||||
self.handleFailure(message: ["empty response from ruby process"])
|
||||
$0.writeSemaphore.signal()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
let responseString = string.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
let socketResponse = SocketResponse(payload: responseString)
|
||||
verbose(message: "response is: \(responseString)")
|
||||
switch socketResponse.responseType {
|
||||
case .clientInitiatedCancel:
|
||||
socketDelegate?.commandExecuted(serverResponse: .clientInitiatedCancelAcknowledged) {
|
||||
$0.writeSemaphore.signal()
|
||||
self.closeSession(sendAbort: false)
|
||||
}
|
||||
|
||||
case let .failure(failureInformation, failureClass, failureMessage):
|
||||
LaneFile.fastfileInstance?.onError(currentLane: ArgumentProcessor(args: CommandLine.arguments).currentLane, errorInfo: failureInformation.joined(), errorClass: failureClass, errorMessage: failureMessage)
|
||||
socketDelegate?.commandExecuted(serverResponse: .serverError) {
|
||||
$0.writeSemaphore.signal()
|
||||
self.handleFailure(message: failureMessage.map { m in [m] + failureInformation } ?? failureInformation)
|
||||
}
|
||||
|
||||
case let .parseFailure(failureInformation):
|
||||
socketDelegate?.commandExecuted(serverResponse: .malformedResponse) {
|
||||
$0.writeSemaphore.signal()
|
||||
self.handleFailure(message: failureInformation)
|
||||
}
|
||||
|
||||
case let .readyForNext(returnedObject, closureArgumentValue):
|
||||
socketDelegate?.commandExecuted(serverResponse: .success(returnedObject: returnedObject, closureArgumentValue: closureArgumentValue)) {
|
||||
$0.writeSemaphore.signal()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.2]
|
21
fastlane/swift/SocketClientDelegateProtocol.swift
Normal file
21
fastlane/swift/SocketClientDelegateProtocol.swift
Normal file
@ -0,0 +1,21 @@
|
||||
// SocketClientDelegateProtocol.swift
|
||||
// Copyright (c) 2024 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
|
||||
|
||||
protocol SocketClientDelegateProtocol: AnyObject {
|
||||
func connectionsOpened()
|
||||
func connectionsClosed()
|
||||
func commandExecuted(serverResponse: SocketClientResponse, completion: (SocketClient) -> Void)
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.2]
|
84
fastlane/swift/SocketResponse.swift
Normal file
84
fastlane/swift/SocketResponse.swift
Normal file
@ -0,0 +1,84 @@
|
||||
// SocketResponse.swift
|
||||
// Copyright (c) 2024 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 SocketResponse {
|
||||
enum ResponseType {
|
||||
case parseFailure(failureInformation: [String])
|
||||
case failure(failureInformation: [String], failureClass: String?, failureMessage: String?)
|
||||
case readyForNext(returnedObject: String?, closureArgumentValue: String?)
|
||||
case clientInitiatedCancel
|
||||
|
||||
init(statusDictionary: [String: Any]) {
|
||||
guard let status = statusDictionary["status"] as? String else {
|
||||
self = .parseFailure(failureInformation: ["Message failed to parse from Ruby server"])
|
||||
return
|
||||
}
|
||||
|
||||
if status == "ready_for_next" {
|
||||
verbose(message: "ready for next")
|
||||
let returnedObject = statusDictionary["return_object"] as? String
|
||||
let closureArgumentValue = statusDictionary["closure_argument_value"] as? String
|
||||
self = .readyForNext(returnedObject: returnedObject, closureArgumentValue: closureArgumentValue)
|
||||
return
|
||||
|
||||
} else if status == "cancelled" {
|
||||
self = .clientInitiatedCancel
|
||||
return
|
||||
|
||||
} else if status == "failure" {
|
||||
guard let failureInformation = statusDictionary["failure_information"] as? [String] else {
|
||||
self = .parseFailure(failureInformation: ["Ruby server indicated failure but Swift couldn't receive it"])
|
||||
return
|
||||
}
|
||||
|
||||
let failureClass = statusDictionary["failure_class"] as? String
|
||||
let failureMessage = statusDictionary["failure_message"] as? String
|
||||
self = .failure(failureInformation: failureInformation, failureClass: failureClass, failureMessage: failureMessage)
|
||||
return
|
||||
}
|
||||
self = .parseFailure(failureInformation: ["Message status: \(status) not a supported status"])
|
||||
}
|
||||
}
|
||||
|
||||
let responseType: ResponseType
|
||||
|
||||
init(payload: String) {
|
||||
guard let data = SocketResponse.convertToDictionary(text: payload) else {
|
||||
responseType = .parseFailure(failureInformation: ["Unable to parse message from Ruby server"])
|
||||
return
|
||||
}
|
||||
|
||||
guard case let statusDictionary? = data["payload"] as? [String: Any] else {
|
||||
responseType = .parseFailure(failureInformation: ["Payload missing from Ruby server response"])
|
||||
return
|
||||
}
|
||||
|
||||
responseType = ResponseType(statusDictionary: statusDictionary)
|
||||
}
|
||||
}
|
||||
|
||||
extension SocketResponse {
|
||||
static func convertToDictionary(text: String) -> [String: Any]? {
|
||||
if let data = text.data(using: .utf8) {
|
||||
do {
|
||||
return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
|
||||
} catch {
|
||||
log(message: error.localizedDescription)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.2]
|
1
fastlane/swift/formatting/Brewfile
Normal file
1
fastlane/swift/formatting/Brewfile
Normal file
@ -0,0 +1 @@
|
||||
brew("swiftformat")
|
94
fastlane/swift/formatting/Brewfile.lock.json
Normal file
94
fastlane/swift/formatting/Brewfile.lock.json
Normal file
@ -0,0 +1,94 @@
|
||||
{
|
||||
"entries": {
|
||||
"brew": {
|
||||
"swiftformat": {
|
||||
"version": "0.53.5",
|
||||
"bottle": {
|
||||
"rebuild": 0,
|
||||
"root_url": "https://ghcr.io/v2/homebrew/core",
|
||||
"files": {
|
||||
"arm64_sonoma": {
|
||||
"cellar": ":any_skip_relocation",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:04e089d4b1ae1217dd6c8133b3c661add56d7c4f4f24ee67becd3cf8f54e6e80",
|
||||
"sha256": "04e089d4b1ae1217dd6c8133b3c661add56d7c4f4f24ee67becd3cf8f54e6e80"
|
||||
},
|
||||
"arm64_ventura": {
|
||||
"cellar": ":any_skip_relocation",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:19a6ce102e7df1cdee150dee619025aa3b2a4980070bee4f8cdd6976c0936d46",
|
||||
"sha256": "19a6ce102e7df1cdee150dee619025aa3b2a4980070bee4f8cdd6976c0936d46"
|
||||
},
|
||||
"arm64_monterey": {
|
||||
"cellar": ":any_skip_relocation",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:745ba037da0e1fe62f2f22faa45a17655b89d8870bacd9db32597ce1fd779509",
|
||||
"sha256": "745ba037da0e1fe62f2f22faa45a17655b89d8870bacd9db32597ce1fd779509"
|
||||
},
|
||||
"sonoma": {
|
||||
"cellar": ":any_skip_relocation",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:6830f0bd5d06dca19d2bcd614e6d0c87e7a3d703d33bce90d0448a83310dddcc",
|
||||
"sha256": "6830f0bd5d06dca19d2bcd614e6d0c87e7a3d703d33bce90d0448a83310dddcc"
|
||||
},
|
||||
"ventura": {
|
||||
"cellar": ":any_skip_relocation",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:dacbfeca6cbe99fc73448f08c0289f135e807bc220ac1dcb61952410f1b43535",
|
||||
"sha256": "dacbfeca6cbe99fc73448f08c0289f135e807bc220ac1dcb61952410f1b43535"
|
||||
},
|
||||
"monterey": {
|
||||
"cellar": ":any_skip_relocation",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:a5e30f5378aca201ca8bc7a350ebac28b3202366be1b37cf254f77c27761753a",
|
||||
"sha256": "a5e30f5378aca201ca8bc7a350ebac28b3202366be1b37cf254f77c27761753a"
|
||||
},
|
||||
"x86_64_linux": {
|
||||
"cellar": "/home/linuxbrew/.linuxbrew/Cellar",
|
||||
"url": "https://ghcr.io/v2/homebrew/core/swiftformat/blobs/sha256:909ae79dbe735c9377355e202d07a58aeff1af1707ba7a3c843cf7c3b10f68a9",
|
||||
"sha256": "909ae79dbe735c9377355e202d07a58aeff1af1707ba7a3c843cf7c3b10f68a9"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"system": {
|
||||
"macos": {
|
||||
"catalina": {
|
||||
"HOMEBREW_VERSION": "3.2.0-77-gd305f72",
|
||||
"HOMEBREW_PREFIX": "/usr/local",
|
||||
"Homebrew/homebrew-core": "0b13b342053d414d1b241c2c7a446b74d79cc90e",
|
||||
"CLT": "11.0.0.33.12",
|
||||
"Xcode": "12.4",
|
||||
"macOS": "10.15.7"
|
||||
},
|
||||
"big_sur": {
|
||||
"HOMEBREW_VERSION": "3.3.9-34-g2e92128",
|
||||
"HOMEBREW_PREFIX": "/usr/local",
|
||||
"Homebrew/homebrew-core": "c28163ed56d6e54f2f71ecf678d4b4d33bac23a5",
|
||||
"CLT": "12.4.0.0.1.1610135815",
|
||||
"Xcode": "12.5",
|
||||
"macOS": "11.0.1"
|
||||
},
|
||||
"monterey": {
|
||||
"HOMEBREW_VERSION": "3.6.10-11-gb683beb",
|
||||
"HOMEBREW_PREFIX": "/opt/homebrew",
|
||||
"Homebrew/homebrew-core": "0bc04af3657134103a6f2b48b31e278e2537e85f",
|
||||
"CLT": "13.4.0.0.1.1651278267",
|
||||
"Xcode": "13.4.1",
|
||||
"macOS": "12.5"
|
||||
},
|
||||
"ventura": {
|
||||
"HOMEBREW_VERSION": "4.2.2-4-g080e61f",
|
||||
"HOMEBREW_PREFIX": "/opt/homebrew",
|
||||
"Homebrew/homebrew-core": "api",
|
||||
"CLT": "15.0.0.0.1.1694021235",
|
||||
"Xcode": "15.1",
|
||||
"macOS": "13.6"
|
||||
},
|
||||
"sonoma": {
|
||||
"HOMEBREW_VERSION": "4.2.16-71-g044e48b",
|
||||
"HOMEBREW_PREFIX": "/opt/homebrew",
|
||||
"Homebrew/homebrew-core": "api",
|
||||
"CLT": "15.0.0.0.1.1694021235",
|
||||
"Xcode": "15.3",
|
||||
"macOS": "14.2.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
18
fastlane/swift/formatting/Rakefile
Normal file
18
fastlane/swift/formatting/Rakefile
Normal file
@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
task(default: %w[setup])
|
||||
|
||||
task(setup: [:brew, :lint])
|
||||
|
||||
task(:brew) do
|
||||
raise '`brew` is required. Please install brew. https://brew.sh/' unless system('which brew')
|
||||
|
||||
puts('➡️ Brew')
|
||||
sh('brew bundle')
|
||||
end
|
||||
|
||||
task(:lint) do
|
||||
Dir.chdir('..') do
|
||||
sh("swiftformat . --config formatting/.swiftformat --verbose --selfrequired waitWithPolling --exclude Fastfile.swift --swiftversion 4.0")
|
||||
end
|
||||
end
|
47
fastlane/swift/main.swift
Normal file
47
fastlane/swift/main.swift
Normal file
@ -0,0 +1,47 @@
|
||||
// main.swift
|
||||
// Copyright (c) 2024 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
|
||||
|
||||
let argumentProcessor = ArgumentProcessor(args: CommandLine.arguments)
|
||||
let timeout = argumentProcessor.commandTimeout
|
||||
|
||||
class MainProcess {
|
||||
var doneRunningLane = false
|
||||
var thread: Thread!
|
||||
|
||||
@objc func connectToFastlaneAndRunLane() {
|
||||
runner.startSocketThread(port: argumentProcessor.port)
|
||||
|
||||
let completedRun = Fastfile.runLane(from: nil, named: argumentProcessor.currentLane, with: argumentProcessor.laneParameters())
|
||||
if completedRun {
|
||||
runner.disconnectFromFastlaneProcess()
|
||||
}
|
||||
|
||||
doneRunningLane = true
|
||||
}
|
||||
|
||||
func startFastlaneThread() {
|
||||
thread = Thread(target: self, selector: #selector(connectToFastlaneAndRunLane), object: nil)
|
||||
thread.name = "worker thread"
|
||||
thread.start()
|
||||
}
|
||||
}
|
||||
|
||||
let process = MainProcess()
|
||||
process.startFastlaneThread()
|
||||
|
||||
while !process.doneRunningLane, RunLoop.current.run(mode: RunLoopMode.defaultRunLoopMode, before: Date(timeIntervalSinceNow: 2)) {
|
||||
// no op
|
||||
}
|
||||
|
||||
// Please don't remove the lines below
|
||||
// They are used to detect outdated files
|
||||
// FastlaneRunnerAPIVersion [0.9.2]
|
1
fastlane/swift/upgrade_manifest.json
Normal file
1
fastlane/swift/upgrade_manifest.json
Normal file
@ -0,0 +1 @@
|
||||
{"Actions.swift":"Autogenerated API","Fastlane.swift":"Autogenerated API","DeliverfileProtocol.swift":"Autogenerated API","GymfileProtocol.swift":"Autogenerated API","MatchfileProtocol.swift":"Autogenerated API","Plugins.swift":"Autogenerated API","PrecheckfileProtocol.swift":"Autogenerated API","ScanfileProtocol.swift":"Autogenerated API","ScreengrabfileProtocol.swift":"Autogenerated API","SnapshotfileProtocol.swift":"Autogenerated API","LaneFileProtocol.swift":"Fastfile Components","OptionalConfigValue.swift":"Fastfile Components","Atomic.swift":"Networking","ControlCommand.swift":"Networking","RubyCommand.swift":"Networking","RubyCommandable.swift":"Networking","Runner.swift":"Networking","SocketClient.swift":"Networking","SocketClientDelegateProtocol.swift":"Networking","SocketResponse.swift":"Networking","main.swift":"Runner Code","ArgumentProcessor.swift":"Runner Code","RunnerArgument.swift":"Runner Code"}
|
Loading…
Reference in New Issue
Block a user