Cloud to lab (#2993)
This commit is contained in:
parent
49761cbd7c
commit
6e58ef29d6
|
@ -153,7 +153,7 @@ let package = Package(
|
|||
"TuistSigning",
|
||||
"TuistDependencies",
|
||||
"TuistLinting",
|
||||
"TuistCloud",
|
||||
"TuistLab",
|
||||
"TuistDoc",
|
||||
"GraphViz",
|
||||
"TuistMigration",
|
||||
|
@ -178,7 +178,7 @@ let package = Package(
|
|||
"TuistCacheTesting",
|
||||
"TuistGeneratorTesting",
|
||||
"TuistScaffoldTesting",
|
||||
"TuistCloudTesting",
|
||||
"TuistLabTesting",
|
||||
"TuistAutomationTesting",
|
||||
"TuistSigningTesting",
|
||||
"TuistDependenciesTesting",
|
||||
|
@ -202,7 +202,7 @@ let package = Package(
|
|||
"ProjectAutomation",
|
||||
rxBlockingDependency,
|
||||
"TuistLoaderTesting",
|
||||
"TuistCloudTesting",
|
||||
"TuistLabTesting",
|
||||
"TuistGraphTesting",
|
||||
]
|
||||
),
|
||||
|
@ -370,7 +370,7 @@ let package = Package(
|
|||
]
|
||||
),
|
||||
.target(
|
||||
name: "TuistCloud",
|
||||
name: "TuistLab",
|
||||
dependencies: [
|
||||
"XcodeProj",
|
||||
swiftToolsSupportDependency,
|
||||
|
@ -381,9 +381,9 @@ let package = Package(
|
|||
]
|
||||
),
|
||||
.testTarget(
|
||||
name: "TuistCloudTests",
|
||||
name: "TuistLabTests",
|
||||
dependencies: [
|
||||
"TuistCloud",
|
||||
"TuistLab",
|
||||
"TuistSupportTesting",
|
||||
"TuistCoreTesting",
|
||||
rxBlockingDependency,
|
||||
|
@ -391,9 +391,9 @@ let package = Package(
|
|||
]
|
||||
),
|
||||
.target(
|
||||
name: "TuistCloudTesting",
|
||||
name: "TuistLabTesting",
|
||||
dependencies: [
|
||||
"TuistCloud",
|
||||
"TuistLab",
|
||||
swiftToolsSupportDependency,
|
||||
"TuistCore",
|
||||
rxTestDependency,
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
import Foundation
|
||||
|
||||
/// Cloud represents the configuration to connect to the server.
|
||||
public struct Cloud: Codable, Equatable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case url
|
||||
case projectId = "project_id"
|
||||
case options
|
||||
}
|
||||
|
||||
/// Cloud option.
|
||||
public enum Option: String, Codable, Equatable {
|
||||
case insights
|
||||
}
|
||||
|
||||
/// The base URL that points to the cloud server
|
||||
public let url: String
|
||||
|
||||
/// The project unique identifier.
|
||||
public let projectId: String
|
||||
|
||||
/// Cloud options.
|
||||
public let options: [Option]
|
||||
|
||||
/// Initializes a new Cloud configuration instance.
|
||||
/// - Parameters:
|
||||
/// - projectId: Project unique identifier.
|
||||
/// - url: Base URL to the cloud server.
|
||||
/// - options: Cloud options.
|
||||
/// - Returns: A Cloud instance.
|
||||
public static func cloud(projectId: String, url: String, options: [Option] = []) -> Cloud {
|
||||
Cloud(url: url, projectId: projectId, options: options)
|
||||
}
|
||||
}
|
|
@ -45,8 +45,8 @@ public struct Config: Codable, Equatable {
|
|||
/// List of `Plugin`s used to extend Tuist.
|
||||
public let plugins: [PluginLocation]
|
||||
|
||||
/// Cloud configuration.
|
||||
public let cloud: Cloud?
|
||||
/// Lab configuration.
|
||||
public let lab: Lab?
|
||||
|
||||
/// Cache configuration.
|
||||
public let cache: Cache?
|
||||
|
@ -55,13 +55,13 @@ public struct Config: Codable, Equatable {
|
|||
///
|
||||
/// - Parameters:
|
||||
/// - compatibleXcodeVersions: List of Xcode versions the project is compatible with.
|
||||
/// - cloud: Cloud configuration.
|
||||
/// - lab: Lab configuration.
|
||||
/// - cache: Cache configuration.
|
||||
/// - plugins: A list of plugins to extend Tuist.
|
||||
/// - generationOptions: List of options to use when generating the project.
|
||||
public init(
|
||||
compatibleXcodeVersions: CompatibleXcodeVersions = .all,
|
||||
cloud: Cloud? = nil,
|
||||
lab: Lab? = nil,
|
||||
cache: Cache? = nil,
|
||||
plugins: [PluginLocation] = [],
|
||||
generationOptions: [GenerationOptions]
|
||||
|
@ -69,7 +69,7 @@ public struct Config: Codable, Equatable {
|
|||
self.compatibleXcodeVersions = compatibleXcodeVersions
|
||||
self.plugins = plugins
|
||||
self.generationOptions = generationOptions
|
||||
self.cloud = cloud
|
||||
self.lab = lab
|
||||
self.cache = cache
|
||||
dumpIfNeeded(self)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import Foundation
|
||||
|
||||
/// Lab represents the configuration to connect to the server.
|
||||
public struct Lab: Codable, Equatable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case url
|
||||
case projectId = "project_id"
|
||||
case options
|
||||
}
|
||||
|
||||
/// Lab option.
|
||||
public enum Option: String, Codable, Equatable {
|
||||
case insights
|
||||
}
|
||||
|
||||
/// The base URL that points to the Lab server
|
||||
public let url: String
|
||||
|
||||
/// The project unique identifier.
|
||||
public let projectId: String
|
||||
|
||||
/// Lab options.
|
||||
public let options: [Option]
|
||||
|
||||
/// Initializes a new Lab configuration instance.
|
||||
/// - Parameters:
|
||||
/// - projectId: Project unique identifier.
|
||||
/// - url: Base URL to the Lab server.
|
||||
/// - options: Lab options.
|
||||
/// - Returns: A Lab instance.
|
||||
public static func lab(projectId: String, url: String, options: [Option] = []) -> Lab {
|
||||
Lab(url: url, projectId: projectId, options: options)
|
||||
}
|
||||
}
|
|
@ -26,34 +26,34 @@ enum CacheRemoteStorageError: FatalError, Equatable {
|
|||
public final class CacheRemoteStorage: CacheStoring {
|
||||
// MARK: - Attributes
|
||||
|
||||
private let cloudClient: CloudClienting
|
||||
private let labClient: LabClienting
|
||||
private let fileClient: FileClienting
|
||||
private let fileArchiverFactory: FileArchivingFactorying
|
||||
private let cloudCacheResponseFactory: CloudCacheResourceFactorying
|
||||
private let labCacheResourceFactory: LabCacheResourceFactorying
|
||||
private let cacheDirectoriesProvider: CacheDirectoriesProviding
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
public convenience init(cloudConfig: Cloud, cloudClient: CloudClienting, cacheDirectoriesProvider: CacheDirectoriesProviding) {
|
||||
public convenience init(labConfig: Lab, labClient: LabClienting, cacheDirectoriesProvider: CacheDirectoriesProviding) {
|
||||
self.init(
|
||||
cloudClient: cloudClient,
|
||||
labClient: labClient,
|
||||
fileArchiverFactory: FileArchivingFactory(),
|
||||
fileClient: FileClient(),
|
||||
cloudCacheResponseFactory: CloudCacheResourceFactory(cloudConfig: cloudConfig),
|
||||
labCacheResourceFactory: LabCacheResourceFactory(labConfig: labConfig),
|
||||
cacheDirectoriesProvider: cacheDirectoriesProvider
|
||||
)
|
||||
}
|
||||
|
||||
init(cloudClient: CloudClienting,
|
||||
init(labClient: LabClienting,
|
||||
fileArchiverFactory: FileArchivingFactorying,
|
||||
fileClient: FileClienting,
|
||||
cloudCacheResponseFactory: CloudCacheResourceFactorying,
|
||||
labCacheResourceFactory: LabCacheResourceFactorying,
|
||||
cacheDirectoriesProvider: CacheDirectoriesProviding)
|
||||
{
|
||||
self.cloudClient = cloudClient
|
||||
self.labClient = labClient
|
||||
self.fileArchiverFactory = fileArchiverFactory
|
||||
self.fileClient = fileClient
|
||||
self.cloudCacheResponseFactory = cloudCacheResponseFactory
|
||||
self.labCacheResourceFactory = labCacheResourceFactory
|
||||
self.cacheDirectoriesProvider = cacheDirectoriesProvider
|
||||
}
|
||||
|
||||
|
@ -62,8 +62,8 @@ public final class CacheRemoteStorage: CacheStoring {
|
|||
public func exists(hash: String) -> Single<Bool> {
|
||||
do {
|
||||
let successRange = 200 ..< 300
|
||||
let resource = try cloudCacheResponseFactory.existsResource(hash: hash)
|
||||
return cloudClient.request(resource)
|
||||
let resource = try labCacheResourceFactory.existsResource(hash: hash)
|
||||
return labClient.request(resource)
|
||||
.flatMap { _, response in
|
||||
.just(successRange.contains(response.statusCode))
|
||||
}
|
||||
|
@ -81,8 +81,8 @@ public final class CacheRemoteStorage: CacheStoring {
|
|||
|
||||
public func fetch(hash: String) -> Single<AbsolutePath> {
|
||||
do {
|
||||
let resource = try cloudCacheResponseFactory.fetchResource(hash: hash)
|
||||
return cloudClient
|
||||
let resource = try labCacheResourceFactory.fetchResource(hash: hash)
|
||||
return labClient
|
||||
.request(resource)
|
||||
.map(\.object.data.url)
|
||||
.flatMap { (url: URL) in
|
||||
|
@ -107,12 +107,12 @@ public final class CacheRemoteStorage: CacheStoring {
|
|||
let archiver = try fileArchiverFactory.makeFileArchiver(for: paths)
|
||||
let destinationZipPath = try archiver.zip(name: hash)
|
||||
let md5 = try FileHandler.shared.urlSafeBase64MD5(path: destinationZipPath)
|
||||
let storeResource = try cloudCacheResponseFactory.storeResource(
|
||||
let storeResource = try labCacheResourceFactory.storeResource(
|
||||
hash: hash,
|
||||
contentMD5: md5
|
||||
)
|
||||
|
||||
return cloudClient
|
||||
return labClient
|
||||
.request(storeResource)
|
||||
.map { (responseTuple) -> URL in responseTuple.object.data.url }
|
||||
.flatMapCompletable { (url: URL) in
|
||||
|
@ -134,12 +134,12 @@ public final class CacheRemoteStorage: CacheStoring {
|
|||
|
||||
private func verify(hash: String, contentMD5: String) -> Completable {
|
||||
do {
|
||||
let verifyUploadResource = try cloudCacheResponseFactory.verifyUploadResource(
|
||||
let verifyUploadResource = try labCacheResourceFactory.verifyUploadResource(
|
||||
hash: hash,
|
||||
contentMD5: contentMD5
|
||||
)
|
||||
|
||||
return cloudClient
|
||||
return labClient
|
||||
.request(verifyUploadResource).asCompletable()
|
||||
} catch {
|
||||
return Completable.error(error)
|
||||
|
|
|
@ -3,62 +3,60 @@ import TuistCore
|
|||
import TuistGraph
|
||||
import TuistSupport
|
||||
|
||||
typealias CloudExistsResource = HTTPResource<CloudResponse<CloudHEADResponse>, CloudHEADResponseError>
|
||||
|
||||
typealias CloudCacheResource = HTTPResource<CloudResponse<CloudCacheResponse>, CloudResponseError>
|
||||
|
||||
typealias CloudVerifyUploadResource = HTTPResource<CloudResponse<CloudVerifyUploadResponse>, CloudResponseError>
|
||||
typealias LabExistsResource = HTTPResource<LabResponse<LabHEADResponse>, LabHEADResponseError>
|
||||
typealias LabCacheResource = HTTPResource<LabResponse<LabCacheResponse>, LabResponseError>
|
||||
typealias LabVerifyUploadResource = HTTPResource<LabResponse<LabVerifyUploadResponse>, LabResponseError>
|
||||
|
||||
/// Entity responsible for providing cache-related resources
|
||||
protocol CloudCacheResourceFactorying {
|
||||
func existsResource(hash: String) throws -> CloudExistsResource
|
||||
func fetchResource(hash: String) throws -> CloudCacheResource
|
||||
func storeResource(hash: String, contentMD5: String) throws -> CloudCacheResource
|
||||
func verifyUploadResource(hash: String, contentMD5: String) throws -> CloudVerifyUploadResource
|
||||
protocol LabCacheResourceFactorying {
|
||||
func existsResource(hash: String) throws -> LabExistsResource
|
||||
func fetchResource(hash: String) throws -> LabCacheResource
|
||||
func storeResource(hash: String, contentMD5: String) throws -> LabCacheResource
|
||||
func verifyUploadResource(hash: String, contentMD5: String) throws -> LabVerifyUploadResource
|
||||
}
|
||||
|
||||
class CloudCacheResourceFactory: CloudCacheResourceFactorying {
|
||||
private let cloudConfig: Cloud
|
||||
class LabCacheResourceFactory: LabCacheResourceFactorying {
|
||||
private let labConfig: Lab
|
||||
|
||||
init(cloudConfig: Cloud) {
|
||||
self.cloudConfig = cloudConfig
|
||||
init(labConfig: Lab) {
|
||||
self.labConfig = labConfig
|
||||
}
|
||||
|
||||
func existsResource(hash: String) throws -> CloudExistsResource {
|
||||
let url = try apiCacheURL(hash: hash, cacheURL: cloudConfig.url, projectId: cloudConfig.projectId)
|
||||
func existsResource(hash: String) throws -> LabExistsResource {
|
||||
let url = try apiCacheURL(hash: hash, cacheURL: labConfig.url, projectId: labConfig.projectId)
|
||||
var request = URLRequest(url: url)
|
||||
request.httpMethod = "HEAD"
|
||||
return HTTPResource(
|
||||
request: { request },
|
||||
parse: { _, _ in CloudResponse(status: "HEAD", data: CloudHEADResponse()) },
|
||||
parseError: { _, _ in CloudHEADResponseError() }
|
||||
parse: { _, _ in LabResponse(status: "HEAD", data: LabHEADResponse()) },
|
||||
parseError: { _, _ in LabHEADResponseError() }
|
||||
)
|
||||
}
|
||||
|
||||
func fetchResource(hash: String) throws -> CloudCacheResource {
|
||||
func fetchResource(hash: String) throws -> LabCacheResource {
|
||||
let url = try apiCacheURL(
|
||||
hash: hash,
|
||||
cacheURL: cloudConfig.url,
|
||||
projectId: cloudConfig.projectId
|
||||
cacheURL: labConfig.url,
|
||||
projectId: labConfig.projectId
|
||||
)
|
||||
return HTTPResource.jsonResource(for: url, httpMethod: "GET")
|
||||
}
|
||||
|
||||
func storeResource(hash: String, contentMD5: String) throws -> CloudCacheResource {
|
||||
func storeResource(hash: String, contentMD5: String) throws -> LabCacheResource {
|
||||
let url = try apiCacheURL(
|
||||
hash: hash,
|
||||
cacheURL: cloudConfig.url,
|
||||
projectId: cloudConfig.projectId,
|
||||
cacheURL: labConfig.url,
|
||||
projectId: labConfig.projectId,
|
||||
contentMD5: contentMD5
|
||||
)
|
||||
return HTTPResource.jsonResource(for: url, httpMethod: "POST")
|
||||
}
|
||||
|
||||
func verifyUploadResource(hash: String, contentMD5: String) throws -> CloudVerifyUploadResource {
|
||||
func verifyUploadResource(hash: String, contentMD5: String) throws -> LabVerifyUploadResource {
|
||||
let url = try apiCacheVerifyUploadURL(
|
||||
hash: hash,
|
||||
cacheURL: cloudConfig.url,
|
||||
projectId: cloudConfig.projectId,
|
||||
cacheURL: labConfig.url,
|
||||
projectId: labConfig.projectId,
|
||||
contentMD5: contentMD5
|
||||
)
|
||||
return HTTPResource.jsonResource(for: url, httpMethod: "POST")
|
|
@ -1 +0,0 @@
|
|||
struct CloudHEADResponse: Decodable {}
|
|
@ -1,3 +0,0 @@
|
|||
struct CloudVerifyUploadResponse: Decodable {
|
||||
let uploadedSize: Int
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import Foundation
|
||||
|
||||
struct CloudCacheResponse: Decodable {
|
||||
struct LabCacheResponse: Decodable {
|
||||
let url: URL
|
||||
let expiresAt: TimeInterval
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import Foundation
|
||||
|
||||
struct LabHEADResponse: Decodable {}
|
|
@ -0,0 +1,5 @@
|
|||
import Foundation
|
||||
|
||||
struct LabVerifyUploadResponse: Decodable {
|
||||
let uploadedSize: Int
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
import Foundation
|
||||
import TuistCloud
|
||||
import TuistCore
|
||||
import TuistGraph
|
||||
import TuistLab
|
||||
import TuistSupport
|
||||
import TuistSupportTesting
|
||||
@testable import TuistCache
|
||||
@testable import TuistCoreTesting
|
||||
|
||||
public class MockCloudCacheResourceFactory: CloudCacheResourceFactorying {
|
||||
public class MockLabCacheResourceFactory: LabCacheResourceFactorying {
|
||||
public init() {}
|
||||
|
||||
public var invokedExistsResource = false
|
||||
|
@ -15,13 +15,13 @@ public class MockCloudCacheResourceFactory: CloudCacheResourceFactorying {
|
|||
public var invokedExistsResourceParameters: (hash: String, Void)?
|
||||
public var invokedExistsResourceParametersList = [(hash: String, Void)]()
|
||||
public var stubbedExistsResourceError: Error?
|
||||
public var stubbedExistsResourceResult: CloudExistsResource = HTTPResource(
|
||||
public var stubbedExistsResourceResult: LabExistsResource = HTTPResource(
|
||||
request: { URLRequest.test() },
|
||||
parse: { _, _ in CloudResponse(status: "HEAD", data: CloudHEADResponse()) },
|
||||
parseError: { _, _ in CloudHEADResponseError() }
|
||||
parse: { _, _ in LabResponse(status: "HEAD", data: LabHEADResponse()) },
|
||||
parseError: { _, _ in LabHEADResponseError() }
|
||||
)
|
||||
|
||||
public func existsResource(hash: String) throws -> HTTPResource<CloudResponse<CloudHEADResponse>, CloudHEADResponseError> {
|
||||
public func existsResource(hash: String) throws -> HTTPResource<LabResponse<LabHEADResponse>, LabHEADResponseError> {
|
||||
invokedExistsResource = true
|
||||
invokedExistsResourceCount += 1
|
||||
invokedExistsResourceParameters = (hash, ())
|
||||
|
@ -37,13 +37,13 @@ public class MockCloudCacheResourceFactory: CloudCacheResourceFactorying {
|
|||
public var invokedFetchResourceParameters: (hash: String, Void)?
|
||||
public var invokedFetchResourceParametersList = [(hash: String, Void)]()
|
||||
public var stubbedFetchResourceError: Error?
|
||||
public var stubbedFetchResourceResult: CloudCacheResource = HTTPResource(
|
||||
public var stubbedFetchResourceResult: LabCacheResource = HTTPResource(
|
||||
request: { URLRequest.test() },
|
||||
parse: { _, _ in CloudResponse.test(data: CloudCacheResponse.test()) },
|
||||
parseError: { _, _ in CloudResponseError.test() }
|
||||
parse: { _, _ in LabResponse.test(data: LabCacheResponse.test()) },
|
||||
parseError: { _, _ in LabResponseError.test() }
|
||||
)
|
||||
|
||||
public func fetchResource(hash: String) throws -> CloudCacheResource {
|
||||
public func fetchResource(hash: String) throws -> LabCacheResource {
|
||||
invokedFetchResource = true
|
||||
invokedFetchResourceCount += 1
|
||||
invokedFetchResourceParameters = (hash, ())
|
||||
|
@ -59,13 +59,13 @@ public class MockCloudCacheResourceFactory: CloudCacheResourceFactorying {
|
|||
public var invokedStoreResourceParameters: (hash: String, contentMD5: String)?
|
||||
public var invokedStoreResourceParametersList = [(hash: String, contentMD5: String)]()
|
||||
public var stubbedStoreResourceError: Error?
|
||||
public var stubbedStoreResourceResult: CloudCacheResource = HTTPResource(
|
||||
public var stubbedStoreResourceResult: LabCacheResource = HTTPResource(
|
||||
request: { URLRequest.test() },
|
||||
parse: { _, _ in CloudResponse.test(data: CloudCacheResponse.test()) },
|
||||
parseError: { _, _ in CloudResponseError.test() }
|
||||
parse: { _, _ in LabResponse.test(data: LabCacheResponse.test()) },
|
||||
parseError: { _, _ in LabResponseError.test() }
|
||||
)
|
||||
|
||||
public func storeResource(hash: String, contentMD5: String) throws -> CloudCacheResource {
|
||||
public func storeResource(hash: String, contentMD5: String) throws -> LabCacheResource {
|
||||
invokedStoreResource = true
|
||||
invokedStoreResourceCount += 1
|
||||
invokedStoreResourceParameters = (hash, contentMD5)
|
||||
|
@ -81,13 +81,13 @@ public class MockCloudCacheResourceFactory: CloudCacheResourceFactorying {
|
|||
public var invokedVerifyUploadResourceParameters: (hash: String, contentMD5: String)?
|
||||
public var invokedVerifyUploadResourceParametersList = [(hash: String, contentMD5: String)]() // swiftlint:disable:this identifier_name
|
||||
public var stubbedVerifyUploadResourceError: Error?
|
||||
public var stubbedVerifyUploadResourceResult: CloudVerifyUploadResource = HTTPResource(
|
||||
public var stubbedVerifyUploadResourceResult: LabVerifyUploadResource = HTTPResource(
|
||||
request: { URLRequest.test() },
|
||||
parse: { _, _ in CloudResponse.test(data: CloudVerifyUploadResponse.test()) },
|
||||
parseError: { _, _ in CloudResponseError.test() }
|
||||
parse: { _, _ in LabResponse.test(data: LabVerifyUploadResponse.test()) },
|
||||
parseError: { _, _ in LabResponseError.test() }
|
||||
)
|
||||
|
||||
public func verifyUploadResource(hash: String, contentMD5: String) throws -> CloudVerifyUploadResource {
|
||||
public func verifyUploadResource(hash: String, contentMD5: String) throws -> LabVerifyUploadResource {
|
||||
invokedVerifyUploadResource = true
|
||||
invokedVerifyUploadResourceCount += 1
|
||||
invokedVerifyUploadResourceParameters = (hash, contentMD5)
|
|
@ -1,7 +0,0 @@
|
|||
@testable import TuistCache
|
||||
|
||||
extension CloudVerifyUploadResponse {
|
||||
public static func test(uploadedSize: Int = 0) -> CloudVerifyUploadResponse {
|
||||
CloudVerifyUploadResponse(uploadedSize: uploadedSize)
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
import Foundation
|
||||
@testable import TuistCache
|
||||
|
||||
extension CloudCacheResponse {
|
||||
public static func test(url: URL = URL.test(), expiresAt: TimeInterval = 0) -> CloudCacheResponse {
|
||||
CloudCacheResponse(
|
||||
extension LabCacheResponse {
|
||||
public static func test(url: URL = URL.test(), expiresAt: TimeInterval = 0) -> LabCacheResponse {
|
||||
LabCacheResponse(
|
||||
url: url,
|
||||
expiresAt: expiresAt
|
||||
)
|
|
@ -0,0 +1,7 @@
|
|||
@testable import TuistCache
|
||||
|
||||
extension LabVerifyUploadResponse {
|
||||
public static func test(uploadedSize: Int = 0) -> LabVerifyUploadResponse {
|
||||
LabVerifyUploadResponse(uploadedSize: uploadedSize)
|
||||
}
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
import TuistSupport
|
||||
let logger = Logger(label: "io.tuist.cloud")
|
|
@ -2,6 +2,6 @@ import Foundation
|
|||
import RxSwift
|
||||
import TuistSupport
|
||||
|
||||
public protocol CloudClienting {
|
||||
public protocol LabClienting {
|
||||
func request<T, E>(_ resource: HTTPResource<T, E>) -> Single<(object: T, response: HTTPURLResponse)>
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import Foundation
|
||||
|
||||
public struct CloudResponse<T: Decodable>: Decodable {
|
||||
public struct LabResponse<T: Decodable>: Decodable {
|
||||
public let status: String
|
||||
public let data: T
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import Foundation
|
||||
import TuistSupport
|
||||
|
||||
public struct CloudResponseError: Decodable, LocalizedError, Equatable {
|
||||
public struct LabResponseError: Decodable, LocalizedError, Equatable {
|
||||
public var status: String
|
||||
public var errors: [Error]?
|
||||
|
||||
|
@ -15,6 +15,6 @@ public struct CloudResponseError: Decodable, LocalizedError, Equatable {
|
|||
}
|
||||
}
|
||||
|
||||
public struct CloudHEADResponseError: Decodable, LocalizedError, Equatable {
|
||||
public struct LabHEADResponseError: Decodable, LocalizedError, Equatable {
|
||||
public init() {}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
import Foundation
|
||||
@testable import TuistCore
|
||||
|
||||
extension CloudResponse {
|
||||
static func test(status: String = "status", data: T) -> CloudResponse<T> {
|
||||
CloudResponse(status: status, data: data)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
import Foundation
|
||||
@testable import TuistCore
|
||||
|
||||
extension LabResponse {
|
||||
static func test(status: String = "status", data: T) -> LabResponse<T> {
|
||||
LabResponse(status: status, data: data)
|
||||
}
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
import Foundation
|
||||
@testable import TuistCore
|
||||
|
||||
public extension CloudResponseError.Error {
|
||||
static func test(code: String = "Code", message: String = "Message") -> CloudResponseError.Error {
|
||||
public extension LabResponseError.Error {
|
||||
static func test(code: String = "Code", message: String = "Message") -> LabResponseError.Error {
|
||||
.init(code: code, message: message)
|
||||
}
|
||||
}
|
||||
|
||||
public extension CloudResponseError {
|
||||
static func test(status: String = "Error status", errors: [Error]? = [.test()]) -> CloudResponseError {
|
||||
public extension LabResponseError {
|
||||
static func test(status: String = "Error status", errors: [Error]? = [.test()]) -> LabResponseError {
|
||||
.init(status: status, errors: errors)
|
||||
}
|
||||
}
|
|
@ -4,11 +4,11 @@ import TuistSupport
|
|||
|
||||
@testable import TuistCore
|
||||
|
||||
public enum MockCloudClientingError: Error {
|
||||
public enum MockLabClientingError: Error {
|
||||
case mockedError
|
||||
}
|
||||
|
||||
public final class MockCloudClient: CloudClienting {
|
||||
public final class MockLabClient: LabClienting {
|
||||
// MARK: Factories
|
||||
|
||||
public var invokedRequest = false
|
|
@ -18,7 +18,7 @@ public enum BinaryLinking: String, Codable {
|
|||
public extension Sequence where Element == BinaryArchitecture {
|
||||
/// Returns true if all the architectures are only for simulator.
|
||||
var onlySimulator: Bool {
|
||||
let simulatorArchitectures: [BinaryArchitecture] = [.x8664, .i386]
|
||||
let simulatorArchitectures: [BinaryArchitecture] = [.x8664, .i386, .arm64]
|
||||
return allSatisfy { simulatorArchitectures.contains($0) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ public struct Config: Equatable, Hashable {
|
|||
/// List of Xcode versions the project or set of projects is compatible with.
|
||||
public let compatibleXcodeVersions: CompatibleXcodeVersions
|
||||
|
||||
/// Cloud configuration.
|
||||
public let cloud: Cloud?
|
||||
/// Lab configuration.
|
||||
public let lab: Lab?
|
||||
|
||||
/// Cache configuration.
|
||||
public let cache: Cache?
|
||||
|
@ -40,26 +40,26 @@ public struct Config: Equatable, Hashable {
|
|||
|
||||
/// Returns the default Tuist configuration.
|
||||
public static var `default`: Config {
|
||||
Config(compatibleXcodeVersions: .all, cloud: nil, cache: nil, plugins: [], generationOptions: [], path: nil)
|
||||
Config(compatibleXcodeVersions: .all, lab: nil, cache: nil, plugins: [], generationOptions: [], path: nil)
|
||||
}
|
||||
|
||||
/// Initializes the tuist cofiguration.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - compatibleXcodeVersions: List of Xcode versions the project or set of projects is compatible with.
|
||||
/// - cloud: Cloud configuration.
|
||||
/// - lab: Lab configuration.
|
||||
/// - plugins: List of locations to a `Plugin` manifest.
|
||||
/// - generationOptions: Generation options.
|
||||
/// - path: The path of the config file.
|
||||
public init(compatibleXcodeVersions: CompatibleXcodeVersions,
|
||||
cloud: Cloud?,
|
||||
lab: Lab?,
|
||||
cache: Cache?,
|
||||
plugins: [PluginLocation],
|
||||
generationOptions: [GenerationOption],
|
||||
path: AbsolutePath?)
|
||||
{
|
||||
self.compatibleXcodeVersions = compatibleXcodeVersions
|
||||
self.cloud = cloud
|
||||
self.lab = lab
|
||||
self.cache = cache
|
||||
self.plugins = plugins
|
||||
self.generationOptions = generationOptions
|
||||
|
@ -70,7 +70,7 @@ public struct Config: Equatable, Hashable {
|
|||
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(generationOptions)
|
||||
hasher.combine(cloud)
|
||||
hasher.combine(lab)
|
||||
hasher.combine(cache)
|
||||
hasher.combine(compatibleXcodeVersions)
|
||||
}
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
import Foundation
|
||||
|
||||
/// Cloud represents the configuration to connect to the server.
|
||||
public struct Cloud: Equatable, Hashable {
|
||||
/// Cloud option.
|
||||
/// Lab represents the configuration to connect to the server.
|
||||
public struct Lab: Equatable, Hashable {
|
||||
/// Lab option.
|
||||
public enum Option: String, Codable, Equatable {
|
||||
case insights
|
||||
}
|
||||
|
||||
/// The base URL that points to the cloud server
|
||||
/// The base URL that points to the lab server
|
||||
public let url: URL
|
||||
|
||||
/// The project unique identifier.
|
||||
public let projectId: String
|
||||
|
||||
/// Cloud options.
|
||||
/// Lab options.
|
||||
public let options: [Option]
|
||||
|
||||
/// Initializes an instance of Cloud.
|
||||
/// Initializes an instance of Lab.
|
||||
/// - Parameters:
|
||||
/// - url: Cloud server base URL.
|
||||
/// - url: Lab server base URL.
|
||||
/// - projectId: Project unique identifier.
|
||||
/// - options: Cloud options.
|
||||
/// - options: Lab options.
|
||||
public init(url: URL, projectId: String, options: [Option]) {
|
||||
self.url = url
|
||||
self.projectId = projectId
|
|
@ -4,7 +4,7 @@ import TSCBasic
|
|||
|
||||
public extension Config {
|
||||
static func test(compatibleXcodeVersions: CompatibleXcodeVersions = .all,
|
||||
cloud: Cloud? = Cloud.test(),
|
||||
lab: Lab? = Lab.test(),
|
||||
cache: Cache? = Cache.test(),
|
||||
plugins: [PluginLocation] = [],
|
||||
generationOptions: [GenerationOption] = [],
|
||||
|
@ -12,7 +12,7 @@ public extension Config {
|
|||
{
|
||||
Config(
|
||||
compatibleXcodeVersions: compatibleXcodeVersions,
|
||||
cloud: cloud,
|
||||
lab: lab,
|
||||
cache: cache,
|
||||
plugins: plugins,
|
||||
generationOptions: generationOptions,
|
||||
|
|
|
@ -3,11 +3,11 @@ import TSCBasic
|
|||
import TuistSupportTesting
|
||||
@testable import TuistGraph
|
||||
|
||||
public extension Cloud {
|
||||
public extension Lab {
|
||||
static func test(url: URL = URL.test(),
|
||||
projectId: String = "123",
|
||||
options: [Cloud.Option] = []) -> Cloud
|
||||
options: [Lab.Option] = []) -> Lab
|
||||
{
|
||||
Cloud(url: url, projectId: projectId, options: options)
|
||||
Lab(url: url, projectId: projectId, options: options)
|
||||
}
|
||||
}
|
|
@ -4,10 +4,10 @@ import RxSwift
|
|||
import TSCBasic
|
||||
import TuistAutomation
|
||||
import TuistCache
|
||||
import TuistCloud
|
||||
import TuistCore
|
||||
import TuistGenerator
|
||||
import TuistGraph
|
||||
import TuistLab
|
||||
import TuistLoader
|
||||
import TuistSupport
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import Foundation
|
||||
import TuistCache
|
||||
import TuistCloud
|
||||
import TuistCore
|
||||
import TuistGraph
|
||||
import TuistLab
|
||||
import TuistLoader
|
||||
|
||||
final class CacheStorageProvider: CacheStorageProviding {
|
||||
|
@ -17,8 +17,12 @@ final class CacheStorageProvider: CacheStorageProviding {
|
|||
func storages() throws -> [CacheStoring] {
|
||||
let cacheDirectoriesProvider = try cacheDirectoryProviderFactory.cacheDirectories(config: config)
|
||||
var storages: [CacheStoring] = [CacheLocalStorage(cacheDirectoriesProvider: cacheDirectoriesProvider)]
|
||||
if let cloudConfig = config.cloud {
|
||||
let storage = CacheRemoteStorage(cloudConfig: cloudConfig, cloudClient: CloudClient(), cacheDirectoriesProvider: cacheDirectoriesProvider)
|
||||
if let labConfig = config.lab {
|
||||
let storage = CacheRemoteStorage(
|
||||
labConfig: labConfig,
|
||||
labClient: LabClient(),
|
||||
cacheDirectoriesProvider: cacheDirectoriesProvider
|
||||
)
|
||||
storages.append(storage)
|
||||
}
|
||||
return storages
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
import ArgumentParser
|
||||
import Foundation
|
||||
import TSCBasic
|
||||
|
||||
struct CloudCommand: ParsableCommand {
|
||||
static var configuration: CommandConfiguration {
|
||||
CommandConfiguration(
|
||||
commandName: "cloud",
|
||||
abstract: "A set of commands for cloud features.",
|
||||
subcommands: [
|
||||
CloudAuthCommand.self,
|
||||
CloudSessionCommand.self,
|
||||
CloudLogoutCommand.self,
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
|
@ -2,16 +2,16 @@ import ArgumentParser
|
|||
import Foundation
|
||||
import TSCBasic
|
||||
|
||||
struct CloudAuthCommand: ParsableCommand {
|
||||
struct LabAuthCommand: ParsableCommand {
|
||||
static var configuration: CommandConfiguration {
|
||||
CommandConfiguration(
|
||||
commandName: "auth",
|
||||
_superCommandName: "cloud",
|
||||
_superCommandName: "lab",
|
||||
abstract: "Authenticates the user on the server with the URL defined in the Config.swift file"
|
||||
)
|
||||
}
|
||||
|
||||
func run() throws {
|
||||
try CloudAuthService().authenticate()
|
||||
try LabAuthService().authenticate()
|
||||
}
|
||||
}
|
|
@ -2,16 +2,16 @@ import ArgumentParser
|
|||
import Foundation
|
||||
import TSCBasic
|
||||
|
||||
struct CloudLogoutCommand: ParsableCommand {
|
||||
struct LabLogoutCommand: ParsableCommand {
|
||||
static var configuration: CommandConfiguration {
|
||||
CommandConfiguration(
|
||||
commandName: "logout",
|
||||
_superCommandName: "cloud",
|
||||
_superCommandName: "lab",
|
||||
abstract: "Removes any existing session to authenticate on the server with the URL defined in the Config.swift file"
|
||||
)
|
||||
}
|
||||
|
||||
func run() throws {
|
||||
try CloudLogoutService().logout()
|
||||
try LabLogoutService().logout()
|
||||
}
|
||||
}
|
|
@ -2,16 +2,16 @@ import ArgumentParser
|
|||
import Foundation
|
||||
import TSCBasic
|
||||
|
||||
struct CloudSessionCommand: ParsableCommand {
|
||||
struct LabSessionCommand: ParsableCommand {
|
||||
static var configuration: CommandConfiguration {
|
||||
CommandConfiguration(
|
||||
commandName: "session",
|
||||
_superCommandName: "cloud",
|
||||
_superCommandName: "lab",
|
||||
abstract: "Prints any existing session to authenticate on the server with the URL defined in the Config.swift file"
|
||||
)
|
||||
}
|
||||
|
||||
func run() throws {
|
||||
try CloudSessionService().printSession()
|
||||
try LabSessionService().printSession()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
import ArgumentParser
|
||||
import Foundation
|
||||
import TSCBasic
|
||||
|
||||
struct LabCommand: ParsableCommand {
|
||||
static var configuration: CommandConfiguration {
|
||||
CommandConfiguration(
|
||||
commandName: "lab",
|
||||
abstract: "A set of commands for lab features.",
|
||||
subcommands: [
|
||||
LabAuthCommand.self,
|
||||
LabSessionCommand.self,
|
||||
LabLogoutCommand.self,
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
|
@ -25,7 +25,7 @@ public struct TuistCommand: ParsableCommand {
|
|||
CreateIssueCommand.self,
|
||||
ScaffoldCommand.self,
|
||||
InitCommand.self,
|
||||
CloudCommand.self,
|
||||
LabCommand.self,
|
||||
CacheCommand.self,
|
||||
SigningCommand.self,
|
||||
MigrationCommand.self,
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import Foundation
|
||||
import TSCBasic
|
||||
import TuistCache
|
||||
import TuistCloud
|
||||
import TuistCore
|
||||
import TuistGenerator
|
||||
import TuistGraph
|
||||
import TuistLab
|
||||
import TuistSigning
|
||||
|
||||
/// It defines an interface for providing the mappers to be used for a specific configuration.
|
||||
|
|
|
@ -1,39 +1,38 @@
|
|||
import Foundation
|
||||
import TuistCloud
|
||||
import TuistCore
|
||||
import TuistLab
|
||||
import TuistLoader
|
||||
import TuistSupport
|
||||
|
||||
protocol CloudAuthServicing: AnyObject {
|
||||
/// It reads the cloud URL from the project's Config.swift and
|
||||
protocol LabAuthServicing: AnyObject {
|
||||
/// It reads the lab URL from the project's Config.swift and
|
||||
/// authenticates the user on that server storing the credentials
|
||||
/// locally on the keychain
|
||||
func authenticate() throws
|
||||
}
|
||||
|
||||
enum CloudAuthServiceError: FatalError, Equatable {
|
||||
case missingCloudURL
|
||||
enum LabAuthServiceError: FatalError, Equatable {
|
||||
case missingLabURL
|
||||
|
||||
/// Error description.
|
||||
var description: String {
|
||||
switch self {
|
||||
case .missingCloudURL:
|
||||
return "The cloud URL attribute is missing in your project's configuration."
|
||||
case .missingLabURL:
|
||||
return "The lab URL attribute is missing in your project's configuration."
|
||||
}
|
||||
}
|
||||
|
||||
/// Error type.
|
||||
var type: ErrorType {
|
||||
switch self {
|
||||
case .missingCloudURL:
|
||||
case .missingLabURL:
|
||||
return .abort
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class CloudAuthService: CloudAuthServicing {
|
||||
/// Cloud session controller.
|
||||
let cloudSessionController: CloudSessionControlling
|
||||
final class LabAuthService: LabAuthServicing {
|
||||
let labSessionController: LabSessionControlling
|
||||
let configLoader: ConfigLoading
|
||||
|
||||
// MARK: - Init
|
||||
|
@ -42,27 +41,27 @@ final class CloudAuthService: CloudAuthServicing {
|
|||
let manifestLoader = ManifestLoader()
|
||||
let configLoader = ConfigLoader(manifestLoader: manifestLoader)
|
||||
self.init(
|
||||
cloudSessionController: CloudSessionController(),
|
||||
labSessionController: LabSessionController(),
|
||||
configLoader: configLoader
|
||||
)
|
||||
}
|
||||
|
||||
init(
|
||||
cloudSessionController: CloudSessionControlling,
|
||||
labSessionController: LabSessionControlling,
|
||||
configLoader: ConfigLoading
|
||||
) {
|
||||
self.cloudSessionController = cloudSessionController
|
||||
self.labSessionController = labSessionController
|
||||
self.configLoader = configLoader
|
||||
}
|
||||
|
||||
// MARK: - CloudAuthServicing
|
||||
// MARK: - LabAuthServicing
|
||||
|
||||
func authenticate() throws {
|
||||
let path = FileHandler.shared.currentPath
|
||||
let config = try configLoader.loadConfig(path: path)
|
||||
guard let cloudURL = config.cloud?.url else {
|
||||
throw CloudAuthServiceError.missingCloudURL
|
||||
guard let labURL = config.lab?.url else {
|
||||
throw LabAuthServiceError.missingLabURL
|
||||
}
|
||||
try cloudSessionController.authenticate(serverURL: cloudURL)
|
||||
try labSessionController.authenticate(serverURL: labURL)
|
||||
}
|
||||
}
|
|
@ -1,40 +1,38 @@
|
|||
import Foundation
|
||||
import TuistCloud
|
||||
import TuistCore
|
||||
import TuistLab
|
||||
import TuistLoader
|
||||
import TuistSupport
|
||||
|
||||
protocol CloudLogoutServicing: AnyObject {
|
||||
/// It reads the cloud URL from the project's Config.swift and
|
||||
protocol LabLogoutServicing: AnyObject {
|
||||
/// It reads the lab URL from the project's Config.swift and
|
||||
/// and it removes any session associated to that domain from
|
||||
/// the keychain
|
||||
func logout() throws
|
||||
}
|
||||
|
||||
enum CloudLogoutServiceError: FatalError, Equatable {
|
||||
case missingCloudURL
|
||||
enum LabLogoutServiceError: FatalError, Equatable {
|
||||
case missingLabURL
|
||||
|
||||
/// Error description.
|
||||
var description: String {
|
||||
switch self {
|
||||
case .missingCloudURL:
|
||||
return "The cloud URL attribute is missing in your project's configuration."
|
||||
case .missingLabURL:
|
||||
return "The lab URL attribute is missing in your project's configuration."
|
||||
}
|
||||
}
|
||||
|
||||
/// Error type.
|
||||
var type: ErrorType {
|
||||
switch self {
|
||||
case .missingCloudURL:
|
||||
case .missingLabURL:
|
||||
return .abort
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class CloudLogoutService: CloudLogoutServicing {
|
||||
/// Cloud session controller.
|
||||
let cloudSessionController: CloudSessionControlling
|
||||
|
||||
final class LabLogoutService: LabLogoutServicing {
|
||||
let labSessionController: LabSessionControlling
|
||||
let configLoader: ConfigLoading
|
||||
|
||||
// MARK: - Init
|
||||
|
@ -43,27 +41,27 @@ final class CloudLogoutService: CloudLogoutServicing {
|
|||
let manifestLoader = ManifestLoader()
|
||||
let configLoader = ConfigLoader(manifestLoader: manifestLoader)
|
||||
self.init(
|
||||
cloudSessionController: CloudSessionController(),
|
||||
labSessionController: LabSessionController(),
|
||||
configLoader: configLoader
|
||||
)
|
||||
}
|
||||
|
||||
init(
|
||||
cloudSessionController: CloudSessionControlling,
|
||||
labSessionController: LabSessionControlling,
|
||||
configLoader: ConfigLoading
|
||||
) {
|
||||
self.cloudSessionController = cloudSessionController
|
||||
self.labSessionController = labSessionController
|
||||
self.configLoader = configLoader
|
||||
}
|
||||
|
||||
// MARK: - CloudAuthServicing
|
||||
// MARK: - LabAuthServicing
|
||||
|
||||
func logout() throws {
|
||||
let path = FileHandler.shared.currentPath
|
||||
let config = try configLoader.loadConfig(path: path)
|
||||
guard let cloudURL = config.cloud?.url else {
|
||||
throw CloudLogoutServiceError.missingCloudURL
|
||||
guard let labURL = config.lab?.url else {
|
||||
throw LabLogoutServiceError.missingLabURL
|
||||
}
|
||||
try cloudSessionController.logout(serverURL: cloudURL)
|
||||
try labSessionController.logout(serverURL: labURL)
|
||||
}
|
||||
}
|
|
@ -1,40 +1,38 @@
|
|||
import Foundation
|
||||
import TuistCloud
|
||||
import TuistCore
|
||||
import TuistLab
|
||||
import TuistLoader
|
||||
import TuistSupport
|
||||
|
||||
protocol CloudSessionServicing: AnyObject {
|
||||
/// It reads the cloud URL from the project's Config.swift and
|
||||
protocol LabSessionServicing: AnyObject {
|
||||
/// It reads the lab URL from the project's Config.swift and
|
||||
/// prints any existing session in the keychain to authenticate
|
||||
/// on a server identified by that URL.
|
||||
func printSession() throws
|
||||
}
|
||||
|
||||
enum CloudSessionServiceError: FatalError, Equatable {
|
||||
case missingCloudURL
|
||||
enum LabSessionServiceError: FatalError, Equatable {
|
||||
case missingLabURL
|
||||
|
||||
/// Error description.
|
||||
var description: String {
|
||||
switch self {
|
||||
case .missingCloudURL:
|
||||
return "The cloud URL attribute is missing in your project's configuration."
|
||||
case .missingLabURL:
|
||||
return "The lab URL attribute is missing in your project's configuration."
|
||||
}
|
||||
}
|
||||
|
||||
/// Error type.
|
||||
var type: ErrorType {
|
||||
switch self {
|
||||
case .missingCloudURL:
|
||||
case .missingLabURL:
|
||||
return .abort
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class CloudSessionService: CloudSessionServicing {
|
||||
/// Cloud session controller.
|
||||
let cloudSessionController: CloudSessionControlling
|
||||
|
||||
final class LabSessionService: LabSessionServicing {
|
||||
let labSessionController: LabSessionControlling
|
||||
let configLoader: ConfigLoading
|
||||
|
||||
// MARK: - Init
|
||||
|
@ -43,27 +41,27 @@ final class CloudSessionService: CloudSessionServicing {
|
|||
let manifestLoader = ManifestLoader()
|
||||
let configLoader = ConfigLoader(manifestLoader: manifestLoader)
|
||||
self.init(
|
||||
cloudSessionController: CloudSessionController(),
|
||||
labSessionController: LabSessionController(),
|
||||
configLoader: configLoader
|
||||
)
|
||||
}
|
||||
|
||||
init(
|
||||
cloudSessionController: CloudSessionControlling,
|
||||
labSessionController: LabSessionControlling,
|
||||
configLoader: ConfigLoading
|
||||
) {
|
||||
self.cloudSessionController = cloudSessionController
|
||||
self.labSessionController = labSessionController
|
||||
self.configLoader = configLoader
|
||||
}
|
||||
|
||||
// MARK: - CloudAuthServicing
|
||||
// MARK: - LabAuthServicing
|
||||
|
||||
func printSession() throws {
|
||||
let path = FileHandler.shared.currentPath
|
||||
let config = try configLoader.loadConfig(path: path)
|
||||
guard let cloudURL = config.cloud?.url else {
|
||||
throw CloudSessionServiceError.missingCloudURL
|
||||
guard let labURL = config.lab?.url else {
|
||||
throw LabSessionServiceError.missingLabURL
|
||||
}
|
||||
try cloudSessionController.printSession(serverURL: cloudURL)
|
||||
try labSessionController.printSession(serverURL: labURL)
|
||||
}
|
||||
}
|
|
@ -3,18 +3,18 @@ import RxSwift
|
|||
import TuistCore
|
||||
import TuistSupport
|
||||
|
||||
public class CloudClient: CloudClienting {
|
||||
public class LabClient: LabClienting {
|
||||
// MARK: - Attributes
|
||||
|
||||
let cloudHTTPRequestAuthenticator: CloudHTTPRequestAuthenticating
|
||||
let labHTTPRequestAuthenticator: LabHTTPRequestAuthenticating
|
||||
let requestDispatcher: HTTPRequestDispatching
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
public init(cloudHTTPRequestAuthenticator: CloudHTTPRequestAuthenticating = CloudHTTPRequestAuthenticator(),
|
||||
public init(labHTTPRequestAuthenticator: LabHTTPRequestAuthenticating = LabHTTPRequestAuthenticator(),
|
||||
requestDispatcher: HTTPRequestDispatching = HTTPRequestDispatcher())
|
||||
{
|
||||
self.cloudHTTPRequestAuthenticator = cloudHTTPRequestAuthenticator
|
||||
self.labHTTPRequestAuthenticator = labHTTPRequestAuthenticator
|
||||
self.requestDispatcher = requestDispatcher
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ public class CloudClient: CloudClienting {
|
|||
var request = request
|
||||
if request.allHTTPHeaderFields == nil { request.allHTTPHeaderFields = [:] }
|
||||
request.allHTTPHeaderFields?["Content-Type"] = "application/json;"
|
||||
return try self.cloudHTTPRequestAuthenticator.authenticate(request: request)
|
||||
return try self.labHTTPRequestAuthenticator.authenticate(request: request)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import Foundation
|
||||
|
||||
public enum CloudClientError: LocalizedError, Equatable {
|
||||
public enum LabClientError: LocalizedError, Equatable {
|
||||
case unauthorized
|
||||
|
||||
public var errorDescription: String? {
|
|
@ -0,0 +1,2 @@
|
|||
import TuistSupport
|
||||
let logger = Logger(label: "io.tuist.lab")
|
|
@ -1,7 +1,7 @@
|
|||
import Foundation
|
||||
import TuistSupport
|
||||
|
||||
public enum CloudSessionControllerError: FatalError, Equatable {
|
||||
public enum LabSessionControllerError: FatalError, Equatable {
|
||||
case missingParameters
|
||||
case authenticationError(String)
|
||||
case invalidParameters([String])
|
||||
|
@ -28,7 +28,7 @@ public enum CloudSessionControllerError: FatalError, Equatable {
|
|||
}
|
||||
}
|
||||
|
||||
public protocol CloudSessionControlling: AnyObject {
|
||||
public protocol LabSessionControlling: AnyObject {
|
||||
/// It authenticates the user for the server with the given URL.
|
||||
/// - Parameter serverURL: Server URL.
|
||||
func authenticate(serverURL: URL) throws
|
||||
|
@ -42,7 +42,7 @@ public protocol CloudSessionControlling: AnyObject {
|
|||
func logout(serverURL: URL) throws
|
||||
}
|
||||
|
||||
public final class CloudSessionController: CloudSessionControlling {
|
||||
public final class LabSessionController: LabSessionControlling {
|
||||
static let port: UInt16 = 4545
|
||||
|
||||
/// Credentials store.
|
||||
|
@ -77,7 +77,7 @@ public final class CloudSessionController: CloudSessionControlling {
|
|||
self.opener = opener
|
||||
}
|
||||
|
||||
// MARK: - CloudSessionControlling
|
||||
// MARK: - LabSessionControlling
|
||||
|
||||
public func authenticate(serverURL: URL) throws {
|
||||
var components = URLComponents(url: serverURL, resolvingAgainstBaseURL: false)!
|
||||
|
@ -91,7 +91,7 @@ public final class CloudSessionController: CloudSessionControlling {
|
|||
let logoURL = serverURL.appendingPathComponent("redirect-logo.svg")
|
||||
let redirectMessage = "Switch back to your terminal to continue the authentication."
|
||||
let result = httpRedirectListener.listen(
|
||||
port: CloudSessionController.port,
|
||||
port: LabSessionController.port,
|
||||
path: "auth",
|
||||
redirectMessage: redirectMessage,
|
||||
logoURL: logoURL
|
||||
|
@ -100,17 +100,17 @@ public final class CloudSessionController: CloudSessionControlling {
|
|||
case let .failure(error): throw error
|
||||
case let .success(parameters):
|
||||
guard let parameters = parameters else {
|
||||
throw CloudSessionControllerError.missingParameters
|
||||
throw LabSessionControllerError.missingParameters
|
||||
}
|
||||
if let error = parameters["error"] {
|
||||
throw CloudSessionControllerError.authenticationError(error)
|
||||
throw LabSessionControllerError.authenticationError(error)
|
||||
} else if let token = parameters["token"], let account = parameters["account"] {
|
||||
logger.notice("Successfully authenticated. Storing credentials...")
|
||||
let credentials = Credentials(token: token, account: account)
|
||||
try credentialsStore.store(credentials: credentials, serverURL: serverURL)
|
||||
logger.notice("Credentials stored successfully", metadata: .success)
|
||||
} else {
|
||||
throw CloudSessionControllerError.invalidParameters(Array(parameters.keys))
|
||||
throw LabSessionControllerError.invalidParameters(Array(parameters.keys))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,14 +4,14 @@ import TuistSupport
|
|||
/// Protocol that defines the interface to map HTTP requests and include authentication information.
|
||||
/// Depending on th environment where Tuist is running (local or CI), it returns the token from the credentials store (i.e. Keychain)
|
||||
/// or a environment variable.
|
||||
public protocol CloudHTTPRequestAuthenticating {
|
||||
/// Given a request, it returns a copy of it including information to authenticate requests to the cloud.
|
||||
public protocol LabHTTPRequestAuthenticating {
|
||||
/// Given a request, it returns a copy of it including information to authenticate requests to the lab.
|
||||
/// - Parameter request: Request to authenticate.
|
||||
/// - Returns: Mapped request.
|
||||
func authenticate(request: URLRequest) throws -> URLRequest
|
||||
}
|
||||
|
||||
public final class CloudHTTPRequestAuthenticator: CloudHTTPRequestAuthenticating {
|
||||
public final class LabHTTPRequestAuthenticator: LabHTTPRequestAuthenticating {
|
||||
/// Utility to check whether we are running Tuist on CI.
|
||||
let ciChecker: CIChecking
|
||||
|
||||
|
@ -38,7 +38,7 @@ public final class CloudHTTPRequestAuthenticator: CloudHTTPRequestAuthenticating
|
|||
self.credentialsStore = credentialsStore
|
||||
}
|
||||
|
||||
// MARK: - CloudHTTPRequestAuthenticating
|
||||
// MARK: - LabHTTPRequestAuthenticating
|
||||
|
||||
public func authenticate(request: URLRequest) throws -> URLRequest {
|
||||
var urlComponents = URLComponents(url: request.url!, resolvingAgainstBaseURL: false)!
|
||||
|
@ -48,7 +48,7 @@ public final class CloudHTTPRequestAuthenticator: CloudHTTPRequestAuthenticating
|
|||
|
||||
let token: String?
|
||||
if ciChecker.isCI() {
|
||||
token = environmentVariables()[Constants.EnvironmentVariables.cloudToken]
|
||||
token = environmentVariables()[Constants.EnvironmentVariables.labToken]
|
||||
} else {
|
||||
token = try credentialsStore.read(serverURL: serverURL)?.token
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
import Foundation
|
||||
|
||||
@testable import TuistCloud
|
||||
@testable import TuistLab
|
||||
|
||||
public final class MockCloudSessionController: CloudSessionControlling {
|
||||
public final class MockLabSessionController: LabSessionControlling {
|
||||
public init() {}
|
||||
|
||||
public var authenticateArgs: [URL] = []
|
|
@ -2,9 +2,9 @@ import Foundation
|
|||
import TuistSupport
|
||||
import XCTest
|
||||
|
||||
@testable import TuistCloud
|
||||
@testable import TuistLab
|
||||
|
||||
final class MockCloudHTTPRequestAuthenticator: CloudHTTPRequestAuthenticating {
|
||||
final class MockLabHTTPRequestAuthenticator: LabHTTPRequestAuthenticating {
|
||||
public init() {}
|
||||
|
||||
public var authenticateStub: ((URLRequest) throws -> URLRequest)?
|
|
@ -5,41 +5,41 @@ import TuistCore
|
|||
import TuistGraph
|
||||
import TuistSupport
|
||||
|
||||
enum CloudManifestMapperError: FatalError {
|
||||
/// Thrown when the cloud URL is invalid.
|
||||
case invalidCloudURL(String)
|
||||
enum LabManifestMapperError: FatalError {
|
||||
/// Thrown when the lab URL is invalid.
|
||||
case invalidLabURL(String)
|
||||
|
||||
/// Error type.
|
||||
var type: ErrorType {
|
||||
switch self {
|
||||
case .invalidCloudURL: return .abort
|
||||
case .invalidLabURL: return .abort
|
||||
}
|
||||
}
|
||||
|
||||
/// Error description.
|
||||
var description: String {
|
||||
switch self {
|
||||
case let .invalidCloudURL(url):
|
||||
return "The cloud URL '\(url)' is not a valid URL"
|
||||
case let .invalidLabURL(url):
|
||||
return "The lab URL '\(url)' is not a valid URL"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension TuistGraph.Cloud {
|
||||
static func from(manifest: ProjectDescription.Cloud) throws -> TuistGraph.Cloud {
|
||||
var cloudURL: URL!
|
||||
if let manifestCloudURL = URL(string: manifest.url) {
|
||||
cloudURL = manifestCloudURL
|
||||
extension TuistGraph.Lab {
|
||||
static func from(manifest: ProjectDescription.Lab) throws -> TuistGraph.Lab {
|
||||
var labURL: URL!
|
||||
if let manifestLabURL = URL(string: manifest.url) {
|
||||
labURL = manifestLabURL
|
||||
} else {
|
||||
throw CloudManifestMapperError.invalidCloudURL(manifest.url)
|
||||
throw LabManifestMapperError.invalidLabURL(manifest.url)
|
||||
}
|
||||
let options = manifest.options.map(TuistGraph.Cloud.Option.from)
|
||||
return TuistGraph.Cloud(url: cloudURL, projectId: manifest.projectId, options: options)
|
||||
let options = manifest.options.map(TuistGraph.Lab.Option.from)
|
||||
return TuistGraph.Lab(url: labURL, projectId: manifest.projectId, options: options)
|
||||
}
|
||||
}
|
||||
|
||||
extension TuistGraph.Cloud.Option {
|
||||
static func from(manifest: ProjectDescription.Cloud.Option) -> TuistGraph.Cloud.Option {
|
||||
extension TuistGraph.Lab.Option {
|
||||
static func from(manifest: ProjectDescription.Lab.Option) -> TuistGraph.Lab.Option {
|
||||
switch manifest {
|
||||
case .insights:
|
||||
return .insights
|
||||
|
|
|
@ -16,9 +16,9 @@ extension TuistGraph.Config {
|
|||
let generatorPaths = GeneratorPaths(manifestDirectory: path)
|
||||
let plugins = try manifest.plugins.map { try PluginLocation.from(manifest: $0, generatorPaths: generatorPaths) }
|
||||
|
||||
var cloud: TuistGraph.Cloud?
|
||||
if let manifestCloud = manifest.cloud {
|
||||
cloud = try TuistGraph.Cloud.from(manifest: manifestCloud)
|
||||
var lab: TuistGraph.Lab?
|
||||
if let manifestLab = manifest.lab {
|
||||
lab = try TuistGraph.Lab.from(manifest: manifestLab)
|
||||
}
|
||||
|
||||
var cache: TuistGraph.Cache?
|
||||
|
@ -33,7 +33,7 @@ extension TuistGraph.Config {
|
|||
|
||||
return TuistGraph.Config(
|
||||
compatibleXcodeVersions: compatibleXcodeVersions,
|
||||
cloud: cloud,
|
||||
lab: lab,
|
||||
cache: cache,
|
||||
plugins: plugins,
|
||||
generationOptions: generationOptions,
|
||||
|
|
|
@ -61,7 +61,7 @@ public enum Constants {
|
|||
public static let forceConfigCacheDirectory = "TUIST_FORCE_CONFIG_CACHE_DIRECTORY"
|
||||
public static let automationPath = "TUIST_AUTOMATION_PATH"
|
||||
public static let queueDirectory = "TUIST_QUEUE_DIRECTORY"
|
||||
public static let cloudToken = "TUIST_CLOUD_TOKEN"
|
||||
public static let labToken = "TUIST_LAB_TOKEN"
|
||||
public static let cacheManifests = "TUIST_CACHE_MANIFESTS"
|
||||
public static let statsOptOut = "TUIST_STATS_OPT_OUT"
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import XCTest
|
|||
final class ConfigTests: XCTestCase {
|
||||
func test_config_toJSON() throws {
|
||||
let config = Config(
|
||||
cloud: Cloud(url: "https://cloud.tuist.io", projectId: "123", options: [.insights]),
|
||||
lab: Lab(url: "https://lab.tuist.io", projectId: "123", options: [.insights]),
|
||||
generationOptions: [
|
||||
.xcodeProjectName("someprefix-\(.projectName)"),
|
||||
.organizationName("TestOrg"),
|
||||
|
@ -41,7 +41,7 @@ final class ConfigTests: XCTestCase {
|
|||
|
||||
func test_config_toJSON_withAutogeneratedSchemes() throws {
|
||||
let config = Config(
|
||||
cloud: Cloud(url: "https://cloud.tuist.io", projectId: "123", options: [.insights]),
|
||||
lab: Lab(url: "https://lab.tuist.io", projectId: "123", options: [.insights]),
|
||||
generationOptions: [
|
||||
.xcodeProjectName("someprefix-\(.projectName)"),
|
||||
.developmentRegion("de"),
|
||||
|
|
|
@ -2,9 +2,9 @@ import Foundation
|
|||
import XCTest
|
||||
@testable import ProjectDescription
|
||||
|
||||
final class CloudTests: XCTestCase {
|
||||
final class LabTests: XCTestCase {
|
||||
func test_config_toJSON() throws {
|
||||
let cloud = Cloud(url: "https://cloud.tuist.io", projectId: "123", options: [.insights])
|
||||
let cloud = Lab(url: "https://lab.tuist.io", projectId: "123", options: [.insights])
|
||||
XCTAssertCodable(cloud)
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
import RxSwift
|
||||
import TSCBasic
|
||||
import TuistCacheTesting
|
||||
import TuistCloud
|
||||
import TuistCore
|
||||
import TuistGraph
|
||||
import TuistGraphTesting
|
||||
import TuistLab
|
||||
import TuistSupport
|
||||
import XCTest
|
||||
|
||||
|
@ -15,13 +15,13 @@ import XCTest
|
|||
|
||||
final class CacheRemoteStorageTests: TuistUnitTestCase {
|
||||
var subject: CacheRemoteStorage!
|
||||
var cloudClient: MockCloudClient!
|
||||
var labClient: MockLabClient!
|
||||
var fileArchiverFactory: MockFileArchivingFactory!
|
||||
var fileArchiver: MockFileArchiver!
|
||||
var fileUnarchiver: MockFileUnarchiver!
|
||||
var fileClient: MockFileClient!
|
||||
var zipPath: AbsolutePath!
|
||||
var mockCloudCacheResourceFactory: MockCloudCacheResourceFactory!
|
||||
var mockLabCacheResourceFactory: MockLabCacheResourceFactory!
|
||||
let receivedUploadURL = URL(string: "https://remote.storage.com/upload")!
|
||||
var cacheDirectoriesProvider: MockCacheDirectoriesProvider!
|
||||
|
||||
|
@ -30,7 +30,7 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
|
||||
zipPath = fixturePath(path: RelativePath("uUI.xcframework.zip"))
|
||||
|
||||
mockCloudCacheResourceFactory = MockCloudCacheResourceFactory()
|
||||
mockLabCacheResourceFactory = MockLabCacheResourceFactory()
|
||||
fileArchiverFactory = MockFileArchivingFactory()
|
||||
fileArchiver = MockFileArchiver()
|
||||
fileUnarchiver = MockFileUnarchiver()
|
||||
|
@ -39,28 +39,28 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
fileArchiverFactory.stubbedMakeFileUnarchiverResult = fileUnarchiver
|
||||
fileClient = MockFileClient()
|
||||
fileClient.stubbedDownloadResult = Single.just(zipPath)
|
||||
cloudClient = MockCloudClient()
|
||||
labClient = MockLabClient()
|
||||
|
||||
cacheDirectoriesProvider = try MockCacheDirectoriesProvider()
|
||||
cacheDirectoriesProvider.cacheDirectoryStub = try temporaryPath()
|
||||
|
||||
subject = CacheRemoteStorage(
|
||||
cloudClient: cloudClient,
|
||||
labClient: labClient,
|
||||
fileArchiverFactory: fileArchiverFactory,
|
||||
fileClient: fileClient,
|
||||
cloudCacheResponseFactory: mockCloudCacheResourceFactory,
|
||||
labCacheResourceFactory: mockLabCacheResourceFactory,
|
||||
cacheDirectoriesProvider: cacheDirectoriesProvider
|
||||
)
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
subject = nil
|
||||
cloudClient = nil
|
||||
labClient = nil
|
||||
fileArchiver = nil
|
||||
fileArchiverFactory = nil
|
||||
fileClient = nil
|
||||
zipPath = nil
|
||||
mockCloudCacheResourceFactory = nil
|
||||
mockLabCacheResourceFactory = nil
|
||||
cacheDirectoriesProvider = nil
|
||||
super.tearDown()
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
|
||||
func test_exists_whenClientReturnsAnError() throws {
|
||||
// Given
|
||||
cloudClient.mock(error: CloudHEADResponseError())
|
||||
labClient.mock(error: LabHEADResponseError())
|
||||
|
||||
// When
|
||||
let result = subject.exists(hash: "acho tio")
|
||||
|
@ -80,8 +80,8 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
switch result {
|
||||
case .completed:
|
||||
XCTFail("Expected result to complete with error, but result was successful.")
|
||||
case let .failed(_, error) where error is CloudHEADResponseError:
|
||||
XCTAssertEqual(error as! CloudHEADResponseError, CloudHEADResponseError())
|
||||
case let .failed(_, error) where error is LabHEADResponseError:
|
||||
XCTAssertEqual(error as! LabHEADResponseError, LabHEADResponseError())
|
||||
default:
|
||||
XCTFail("Expected result to complete with error, but result error wasn't the expected type.")
|
||||
}
|
||||
|
@ -89,9 +89,9 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
|
||||
func test_exists_whenClientReturnsAnHTTPError() throws {
|
||||
// Given
|
||||
let cloudResponse: CloudResponse<CloudHEADResponse> = CloudResponse(status: "shaki", data: CloudHEADResponse())
|
||||
let labResponse: LabResponse<LabHEADResponse> = LabResponse(status: "shaki", data: LabHEADResponse())
|
||||
let httpResponse: HTTPURLResponse = .test(statusCode: 500)
|
||||
cloudClient.mock(object: cloudResponse, response: httpResponse)
|
||||
labClient.mock(object: labResponse, response: httpResponse)
|
||||
|
||||
// When
|
||||
let result = try subject.exists(hash: "acho tio")
|
||||
|
@ -104,9 +104,9 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
|
||||
func test_exists_whenClientReturnsASuccess() throws {
|
||||
// Given
|
||||
let cloudResponse = CloudResponse<CloudHEADResponse>(status: "shaki", data: CloudHEADResponse())
|
||||
let labResponse = LabResponse<LabHEADResponse>(status: "shaki", data: LabHEADResponse())
|
||||
let httpResponse: HTTPURLResponse = .test()
|
||||
cloudClient.mock(object: cloudResponse, response: httpResponse)
|
||||
labClient.mock(object: labResponse, response: httpResponse)
|
||||
|
||||
// When
|
||||
let result = try subject.exists(hash: "acho tio")
|
||||
|
@ -119,9 +119,9 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
|
||||
func test_exists_whenClientReturnsA202() throws {
|
||||
// Given
|
||||
let cloudResponse = CloudResponse<CloudHEADResponse>(status: "shaki", data: CloudHEADResponse())
|
||||
let labResponse = LabResponse<LabHEADResponse>(status: "shaki", data: LabHEADResponse())
|
||||
let httpResponse: HTTPURLResponse = .test(statusCode: 202)
|
||||
cloudClient.mock(object: cloudResponse, response: httpResponse)
|
||||
labClient.mock(object: labResponse, response: httpResponse)
|
||||
|
||||
// When
|
||||
let result = try subject.exists(hash: "acho tio")
|
||||
|
@ -136,8 +136,8 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
|
||||
func test_fetch_whenClientReturnsAnError() throws {
|
||||
// Given
|
||||
let expectedError: CloudResponseError = .test()
|
||||
cloudClient.mock(error: expectedError)
|
||||
let expectedError: LabResponseError = .test()
|
||||
labClient.mock(error: expectedError)
|
||||
|
||||
// When
|
||||
let result = subject.fetch(hash: "acho tio")
|
||||
|
@ -148,8 +148,8 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
switch result {
|
||||
case .completed:
|
||||
XCTFail("Expected result to complete with error, but result was successful.")
|
||||
case let .failed(_, error) where error is CloudResponseError:
|
||||
XCTAssertEqual(error as! CloudResponseError, expectedError)
|
||||
case let .failed(_, error) where error is LabResponseError:
|
||||
XCTAssertEqual(error as! LabResponseError, expectedError)
|
||||
default:
|
||||
XCTFail("Expected result to complete with error, but result error wasn't the expected type.")
|
||||
}
|
||||
|
@ -158,9 +158,9 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
func test_fetch_whenArchiveContainsIncorrectRootFolderAfterUnzipping_expectErrorThrown() throws {
|
||||
// Given
|
||||
let httpResponse: HTTPURLResponse = .test()
|
||||
let cacheResponse = CloudCacheResponse(url: .test(), expiresAt: 123)
|
||||
let cloudResponse = CloudResponse<CloudCacheResponse>(status: "shaki", data: cacheResponse)
|
||||
cloudClient.mock(object: cloudResponse, response: httpResponse)
|
||||
let cacheResponse = LabCacheResponse(url: .test(), expiresAt: 123)
|
||||
let labResponse = LabResponse<LabCacheResponse>(status: "shaki", data: cacheResponse)
|
||||
labClient.mock(object: labResponse, response: httpResponse)
|
||||
|
||||
let hash = "foobar"
|
||||
let paths = try createFolders(["Unarchived/\(hash)/IncorrectRootFolderAfterUnzipping"])
|
||||
|
@ -185,9 +185,9 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
func test_fetch_whenClientReturnsASuccess_returnsCorrectRootFolderAfterUnzipping() throws {
|
||||
// Given
|
||||
let httpResponse: HTTPURLResponse = .test()
|
||||
let cacheResponse = CloudCacheResponse(url: .test(), expiresAt: 123)
|
||||
let cloudResponse = CloudResponse<CloudCacheResponse>(status: "success", data: cacheResponse)
|
||||
cloudClient.mock(object: cloudResponse, response: httpResponse)
|
||||
let cacheResponse = LabCacheResponse(url: .test(), expiresAt: 123)
|
||||
let labResponse = LabResponse<LabCacheResponse>(status: "success", data: cacheResponse)
|
||||
labClient.mock(object: labResponse, response: httpResponse)
|
||||
|
||||
let hash = "bar_foo"
|
||||
let paths = try createFolders(["Unarchived/\(hash)/myFramework.xcframework"])
|
||||
|
@ -207,9 +207,9 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
// Given
|
||||
let httpResponse: HTTPURLResponse = .test()
|
||||
let url = URL(string: "https://tuist.io/acho/tio")!
|
||||
let cacheResponse = CloudCacheResponse(url: url, expiresAt: 123)
|
||||
let cloudResponse = CloudResponse<CloudCacheResponse>(status: "shaki", data: cacheResponse)
|
||||
cloudClient.mock(object: cloudResponse, response: httpResponse)
|
||||
let cacheResponse = LabCacheResponse(url: url, expiresAt: 123)
|
||||
let labResponse = LabResponse<LabCacheResponse>(status: "shaki", data: cacheResponse)
|
||||
labClient.mock(object: labResponse, response: httpResponse)
|
||||
|
||||
let hash = "foo_bar"
|
||||
let paths = try createFolders(["Unarchived/\(hash)/myFramework.xcframework"])
|
||||
|
@ -227,9 +227,9 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
func test_fetch_whenClientReturnsASuccess_givesFileArchiverTheCorrectDestinationPath() throws {
|
||||
// Given
|
||||
let httpResponse: HTTPURLResponse = .test()
|
||||
let cacheResponse = CloudCacheResponse(url: .test(), expiresAt: 123)
|
||||
let cloudResponse = CloudResponse<CloudCacheResponse>(status: "shaki", data: cacheResponse)
|
||||
cloudClient.mock(object: cloudResponse, response: httpResponse)
|
||||
let cacheResponse = LabCacheResponse(url: .test(), expiresAt: 123)
|
||||
let labResponse = LabResponse<LabCacheResponse>(status: "shaki", data: cacheResponse)
|
||||
labClient.mock(object: labResponse, response: httpResponse)
|
||||
|
||||
let paths = try createFolders(["Unarchived/\(hash)/Framework.framework"])
|
||||
fileUnarchiver.stubbedUnzipResult = paths.first?.parentDirectory
|
||||
|
@ -249,8 +249,8 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
|
||||
func test_store_whenClientReturnsAnError() throws {
|
||||
// Given
|
||||
let expectedError = CloudResponseError.test()
|
||||
cloudClient.mock(error: expectedError)
|
||||
let expectedError = LabResponseError.test()
|
||||
labClient.mock(error: expectedError)
|
||||
|
||||
// When
|
||||
let result = subject.store(hash: "acho tio", paths: [.root])
|
||||
|
@ -261,8 +261,8 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
switch result {
|
||||
case .completed:
|
||||
XCTFail("Expected result to complete with error, but result was successful.")
|
||||
case let .failed(_, error) where error is CloudResponseError:
|
||||
XCTAssertEqual(error as! CloudResponseError, expectedError)
|
||||
case let .failed(_, error) where error is LabResponseError:
|
||||
XCTAssertEqual(error as! LabResponseError, expectedError)
|
||||
default:
|
||||
XCTFail("Expected result to complete with error, but result error wasn't the expected type.")
|
||||
}
|
||||
|
@ -270,7 +270,7 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
|
||||
func test_store_whenClientReturnsASuccess_returnsURLToUpload() throws {
|
||||
// Given
|
||||
configureCloudClientForSuccessfulUpload()
|
||||
configureLabClientForSuccessfulUpload()
|
||||
|
||||
// When
|
||||
_ = subject.store(hash: "foo_bar", paths: [.root])
|
||||
|
@ -288,7 +288,7 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
func test_store_whenClientReturnsASuccess_usesTheRightHashToUpload() throws {
|
||||
// Given
|
||||
let hash = "foo_bar"
|
||||
configureCloudClientForSuccessfulUpload()
|
||||
configureLabClientForSuccessfulUpload()
|
||||
|
||||
// When
|
||||
_ = subject.store(hash: hash, paths: [.root])
|
||||
|
@ -306,7 +306,7 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
func test_store_whenClientReturnsASuccess_usesTheRightZipPathToUpload() throws {
|
||||
// Given
|
||||
let hash = "foo_bar"
|
||||
configureCloudClientForSuccessfulUpload()
|
||||
configureLabClientForSuccessfulUpload()
|
||||
fileArchiver.stubbedZipResult = zipPath
|
||||
|
||||
// When
|
||||
|
@ -324,8 +324,8 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
|
||||
func test_store_whenClientReturnsAnUploadErrorVerifyIsNotCalled() throws {
|
||||
// Given
|
||||
let expectedError = CloudResponseError.test()
|
||||
cloudClient.mock(error: expectedError)
|
||||
let expectedError = LabResponseError.test()
|
||||
labClient.mock(error: expectedError)
|
||||
|
||||
// When
|
||||
_ = subject.store(hash: "acho tio", paths: [.root])
|
||||
|
@ -333,12 +333,12 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
.materialize()
|
||||
|
||||
// Then
|
||||
XCTAssertFalse(mockCloudCacheResourceFactory.invokedVerifyUploadResource)
|
||||
XCTAssertFalse(mockLabCacheResourceFactory.invokedVerifyUploadResource)
|
||||
}
|
||||
|
||||
func test_store_whenFileUploaderReturnsAnErrorFileArchiverIsCalled() throws {
|
||||
// Given
|
||||
configureCloudClientForSuccessfulUpload()
|
||||
configureLabClientForSuccessfulUpload()
|
||||
fileClient.stubbedUploadResult = Single.error(TestError("Error uploading file"))
|
||||
|
||||
// When
|
||||
|
@ -352,7 +352,7 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
|
||||
func test_store_whenFileUploaderReturnsAnErrorVerifyIsNotCalled() throws {
|
||||
// Given
|
||||
configureCloudClientForSuccessfulUpload()
|
||||
configureLabClientForSuccessfulUpload()
|
||||
fileClient.stubbedUploadResult = Single.error(TestError("Error uploading file"))
|
||||
|
||||
// When
|
||||
|
@ -361,7 +361,7 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
.materialize()
|
||||
|
||||
// Then
|
||||
XCTAssertFalse(mockCloudCacheResourceFactory.invokedVerifyUploadResource)
|
||||
XCTAssertFalse(mockLabCacheResourceFactory.invokedVerifyUploadResource)
|
||||
}
|
||||
|
||||
func test_store_whenVerifyFailsTheZipArchiveIsDeleted() throws {
|
||||
|
@ -379,32 +379,32 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
|
||||
// MARK: Private
|
||||
|
||||
private func configureCloudClientForSuccessfulUpload() {
|
||||
private func configureLabClientForSuccessfulUpload() {
|
||||
let uploadURLRequest = URLRequest.test(urlString: "https://tuist.cache.io/store")
|
||||
let verifyUploadURLRequest = URLRequest.test(urlString: "https://tuist.cache.io/verify-upload")
|
||||
|
||||
let receivedUploadURLRequest = URLRequest.test(url: receivedUploadURL)
|
||||
let cacheResponse = CloudCacheResponse(url: receivedUploadURLRequest.url!, expiresAt: 123)
|
||||
let uploadURLObject = CloudResponse<CloudCacheResponse>(status: "uploadURLObject status", data: cacheResponse)
|
||||
let cacheResponse = LabCacheResponse(url: receivedUploadURLRequest.url!, expiresAt: 123)
|
||||
let uploadURLObject = LabResponse<LabCacheResponse>(status: "uploadURLObject status", data: cacheResponse)
|
||||
|
||||
let cloudVerifyUploadResponse = CloudVerifyUploadResponse.test()
|
||||
let verifyUploadObject = CloudResponse<CloudVerifyUploadResponse>(status: "cloudVerifyUploadResponse status", data: cloudVerifyUploadResponse)
|
||||
let cloudVerifyUploadResponse = LabVerifyUploadResponse.test()
|
||||
let verifyUploadObject = LabResponse<LabVerifyUploadResponse>(status: "cloudVerifyUploadResponse status", data: cloudVerifyUploadResponse)
|
||||
|
||||
cloudClient.mock(objectPerURLRequest: [
|
||||
labClient.mock(objectPerURLRequest: [
|
||||
uploadURLRequest: uploadURLObject,
|
||||
verifyUploadURLRequest: verifyUploadObject,
|
||||
])
|
||||
|
||||
mockCloudCacheResourceFactory.stubbedStoreResourceResult = HTTPResource(
|
||||
mockLabCacheResourceFactory.stubbedStoreResourceResult = HTTPResource(
|
||||
request: { uploadURLRequest },
|
||||
parse: { _, _ in uploadURLObject },
|
||||
parseError: { _, _ in CloudResponseError.test() }
|
||||
parseError: { _, _ in LabResponseError.test() }
|
||||
)
|
||||
|
||||
mockCloudCacheResourceFactory.stubbedVerifyUploadResourceResult = HTTPResource(
|
||||
mockLabCacheResourceFactory.stubbedVerifyUploadResourceResult = HTTPResource(
|
||||
request: { verifyUploadURLRequest },
|
||||
parse: { _, _ in verifyUploadObject },
|
||||
parseError: { _, _ in CloudResponseError.test() }
|
||||
parseError: { _, _ in LabResponseError.test() }
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -413,25 +413,25 @@ final class CacheRemoteStorageTests: TuistUnitTestCase {
|
|||
let verifyUploadURLRequest = URLRequest.test(urlString: "https://tuist.cache.io/verify-upload")
|
||||
|
||||
let receivedUploadURLRequest = URLRequest.test(url: receivedUploadURL)
|
||||
let cacheResponse = CloudCacheResponse(url: receivedUploadURLRequest.url!, expiresAt: 123)
|
||||
let uploadURLObject = CloudResponse<CloudCacheResponse>(status: "uploadURLObject status", data: cacheResponse)
|
||||
let cacheResponse = LabCacheResponse(url: receivedUploadURLRequest.url!, expiresAt: 123)
|
||||
let uploadURLObject = LabResponse<LabCacheResponse>(status: "uploadURLObject status", data: cacheResponse)
|
||||
|
||||
let cloudVerifyUploadResponse = CloudVerifyUploadResponse.test()
|
||||
let verifyUploadObject = CloudResponse<CloudVerifyUploadResponse>(status: "cloudVerifyUploadResponse status", data: cloudVerifyUploadResponse)
|
||||
let verifyUploadError = CloudResponseError.test()
|
||||
let cloudVerifyUploadResponse = LabVerifyUploadResponse.test()
|
||||
let verifyUploadObject = LabResponse<LabVerifyUploadResponse>(status: "cloudVerifyUploadResponse status", data: cloudVerifyUploadResponse)
|
||||
let verifyUploadError = LabResponseError.test()
|
||||
|
||||
cloudClient.mock(
|
||||
labClient.mock(
|
||||
objectPerURLRequest: [uploadURLRequest: uploadURLObject],
|
||||
errorPerURLRequest: [verifyUploadURLRequest: verifyUploadError]
|
||||
)
|
||||
|
||||
mockCloudCacheResourceFactory.stubbedStoreResourceResult = HTTPResource(
|
||||
mockLabCacheResourceFactory.stubbedStoreResourceResult = HTTPResource(
|
||||
request: { uploadURLRequest },
|
||||
parse: { _, _ in uploadURLObject },
|
||||
parseError: { _, _ in CloudResponseError.test() }
|
||||
parseError: { _, _ in LabResponseError.test() }
|
||||
)
|
||||
|
||||
mockCloudCacheResourceFactory.stubbedVerifyUploadResourceResult = HTTPResource(
|
||||
mockLabCacheResourceFactory.stubbedVerifyUploadResourceResult = HTTPResource(
|
||||
request: { verifyUploadURLRequest },
|
||||
parse: { _, _ in verifyUploadObject },
|
||||
parseError: { _, _ in verifyUploadError }
|
||||
|
|
|
@ -59,7 +59,7 @@ final class SwiftPackageManagerInteractorTests: TuistUnitTestCase {
|
|||
func test_generate_usesSystemGitCredentials() throws {
|
||||
// Given
|
||||
let temporaryPath = try self.temporaryPath()
|
||||
let config = Config(compatibleXcodeVersions: .all, cloud: nil, cache: nil, plugins: [], generationOptions: [.resolveDependenciesWithSystemScm], path: nil)
|
||||
let config = Config(compatibleXcodeVersions: .all, lab: nil, cache: nil, plugins: [], generationOptions: [.resolveDependenciesWithSystemScm], path: nil)
|
||||
|
||||
let target = anyTarget(dependencies: [
|
||||
.package(product: "Example"),
|
||||
|
|
|
@ -351,7 +351,7 @@ final class MultipleConfigurationsIntegrationTests: TuistUnitTestCase {
|
|||
}
|
||||
|
||||
private func createConfig() -> Config {
|
||||
Config(compatibleXcodeVersions: .all, cloud: nil, cache: .default, plugins: [], generationOptions: [], path: nil)
|
||||
Config(compatibleXcodeVersions: .all, lab: nil, cache: .default, plugins: [], generationOptions: [], path: nil)
|
||||
}
|
||||
|
||||
private func createWorkspace(path: AbsolutePath, projects: [String]) throws -> Workspace {
|
||||
|
|
|
@ -60,7 +60,9 @@ final class CacheXCFrameworkBuilderIntegrationTests: TuistTestCase {
|
|||
XCTAssertEqual(FileHandler.shared.glob(temporaryPath, glob: "*.xcframework").count, 1)
|
||||
let xcframeworkPath = try XCTUnwrap(FileHandler.shared.glob(temporaryPath, glob: "*.xcframework").first)
|
||||
let infoPlist = try self.infoPlist(xcframeworkPath: xcframeworkPath)
|
||||
XCTAssertNotNil(infoPlist.availableLibraries.first(where: { $0.supportedArchitectures.contains("x86_64") }))
|
||||
XCTAssertNotNil(infoPlist.availableLibraries.first(where: { library in
|
||||
library.supportedArchitectures.contains("x86_64") || library.supportedArchitectures.contains("arm64")
|
||||
}))
|
||||
XCTAssertTrue(infoPlist.availableLibraries.allSatisfy { $0.supportedPlatform == "macos" })
|
||||
try FileHandler.shared.delete(xcframeworkPath)
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import Foundation
|
||||
import TuistCache
|
||||
import TuistCloud
|
||||
import TuistCore
|
||||
import TuistCoreTesting
|
||||
import TuistGenerator
|
||||
import TuistLab
|
||||
import TuistSigning
|
||||
import TuistSupport
|
||||
import XCTest
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import Foundation
|
||||
import TuistCache
|
||||
import TuistCloud
|
||||
import TuistCoreTesting
|
||||
import TuistGenerator
|
||||
import TuistGraph
|
||||
import TuistGraphTesting
|
||||
import TuistLab
|
||||
import TuistSupport
|
||||
import XCTest
|
||||
|
||||
|
@ -32,7 +32,7 @@ final class ProjectMapperProviderTests: TuistUnitTestCase {
|
|||
|
||||
// When
|
||||
let got = subject.mapper(
|
||||
config: Config.test(cloud: .test(options: []))
|
||||
config: Config.test(lab: .test(options: []))
|
||||
)
|
||||
|
||||
// Then
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import Foundation
|
||||
import TSCBasic
|
||||
import TuistCache
|
||||
import TuistCloud
|
||||
import TuistCoreTesting
|
||||
import TuistGenerator
|
||||
import TuistGraph
|
||||
import TuistGraphTesting
|
||||
import TuistLab
|
||||
import TuistSupport
|
||||
import XCTest
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import Foundation
|
||||
import TSCBasic
|
||||
import TuistCloudTesting
|
||||
import TuistCore
|
||||
import TuistCoreTesting
|
||||
import TuistGraph
|
||||
import TuistGraphTesting
|
||||
import TuistLabTesting
|
||||
import TuistLoader
|
||||
import TuistLoaderTesting
|
||||
import TuistSupport
|
||||
|
@ -13,21 +13,21 @@ import XCTest
|
|||
@testable import TuistKit
|
||||
@testable import TuistSupportTesting
|
||||
|
||||
final class CloudAuthServiceErrorTests: TuistUnitTestCase {
|
||||
final class LabAuthServiceErrorTests: TuistUnitTestCase {
|
||||
func test_description_when_missingScaleURL() {
|
||||
// Given
|
||||
let subject = CloudAuthServiceError.missingCloudURL
|
||||
let subject = LabAuthServiceError.missingLabURL
|
||||
|
||||
// When
|
||||
let got = subject.description
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, "The cloud URL attribute is missing in your project's configuration.")
|
||||
XCTAssertEqual(got, "The lab URL attribute is missing in your project's configuration.")
|
||||
}
|
||||
|
||||
func test_type_when_missingCloudURL() {
|
||||
// Given
|
||||
let subject = CloudAuthServiceError.missingCloudURL
|
||||
let subject = LabAuthServiceError.missingLabURL
|
||||
|
||||
// When
|
||||
let got = subject.type
|
||||
|
@ -37,24 +37,24 @@ final class CloudAuthServiceErrorTests: TuistUnitTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
final class CloudAuthServiceTests: TuistUnitTestCase {
|
||||
var cloudSessionController: MockCloudSessionController!
|
||||
final class LabAuthServiceTests: TuistUnitTestCase {
|
||||
var labSessionController: MockLabSessionController!
|
||||
var configLoader: MockConfigLoader!
|
||||
var subject: CloudAuthService!
|
||||
var subject: LabAuthService!
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
cloudSessionController = MockCloudSessionController()
|
||||
labSessionController = MockLabSessionController()
|
||||
configLoader = MockConfigLoader()
|
||||
subject = CloudAuthService(
|
||||
cloudSessionController: cloudSessionController,
|
||||
subject = LabAuthService(
|
||||
labSessionController: labSessionController,
|
||||
configLoader: configLoader
|
||||
)
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
super.tearDown()
|
||||
cloudSessionController = nil
|
||||
labSessionController = nil
|
||||
configLoader = nil
|
||||
subject = nil
|
||||
}
|
||||
|
@ -62,24 +62,24 @@ final class CloudAuthServiceTests: TuistUnitTestCase {
|
|||
func test_authenticate_when_cloudURL_is_missing() {
|
||||
// Given
|
||||
configLoader.loadConfigStub = { _ in
|
||||
Config.test(cloud: nil)
|
||||
Config.test(lab: nil)
|
||||
}
|
||||
|
||||
// Then
|
||||
XCTAssertThrowsSpecific(try subject.authenticate(), CloudAuthServiceError.missingCloudURL)
|
||||
XCTAssertThrowsSpecific(try subject.authenticate(), LabAuthServiceError.missingLabURL)
|
||||
}
|
||||
|
||||
func test_authenticate() throws {
|
||||
// Given
|
||||
let cloudURL = URL.test()
|
||||
let labURL = URL.test()
|
||||
configLoader.loadConfigStub = { _ in
|
||||
Config.test(cloud: Cloud(url: cloudURL, projectId: "123", options: []))
|
||||
Config.test(lab: Lab(url: labURL, projectId: "123", options: []))
|
||||
}
|
||||
|
||||
// When
|
||||
try subject.authenticate()
|
||||
|
||||
// Then
|
||||
XCTAssertTrue(cloudSessionController.authenticateArgs.contains(cloudURL))
|
||||
XCTAssertTrue(labSessionController.authenticateArgs.contains(labURL))
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
import Foundation
|
||||
import TSCBasic
|
||||
import TuistCloudTesting
|
||||
import TuistCore
|
||||
import TuistCoreTesting
|
||||
import TuistGraph
|
||||
import TuistGraphTesting
|
||||
import TuistLabTesting
|
||||
import TuistLoader
|
||||
import TuistLoaderTesting
|
||||
import TuistSupport
|
||||
|
@ -13,21 +13,21 @@ import XCTest
|
|||
@testable import TuistKit
|
||||
@testable import TuistSupportTesting
|
||||
|
||||
final class CloudLogoutServiceErrorTests: TuistUnitTestCase {
|
||||
final class LabLogoutServiceErrorTests: TuistUnitTestCase {
|
||||
func test_description_when_missingScaleURL() {
|
||||
// Given
|
||||
let subject = CloudLogoutServiceError.missingCloudURL
|
||||
let subject = LabLogoutServiceError.missingLabURL
|
||||
|
||||
// When
|
||||
let got = subject.description
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, "The cloud URL attribute is missing in your project's configuration.")
|
||||
XCTAssertEqual(got, "The lab URL attribute is missing in your project's configuration.")
|
||||
}
|
||||
|
||||
func test_type_when_missingScaleURL() {
|
||||
func test_type_when_missingLabURL() {
|
||||
// Given
|
||||
let subject = CloudLogoutServiceError.missingCloudURL
|
||||
let subject = LabLogoutServiceError.missingLabURL
|
||||
|
||||
// When
|
||||
let got = subject.type
|
||||
|
@ -37,24 +37,24 @@ final class CloudLogoutServiceErrorTests: TuistUnitTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
final class CloudLogoutServiceTests: TuistUnitTestCase {
|
||||
var cloudSessionController: MockCloudSessionController!
|
||||
final class LabLogoutServiceTests: TuistUnitTestCase {
|
||||
var labSessionController: MockLabSessionController!
|
||||
var configLoader: MockConfigLoader!
|
||||
var subject: CloudLogoutService!
|
||||
var subject: LabLogoutService!
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
cloudSessionController = MockCloudSessionController()
|
||||
labSessionController = MockLabSessionController()
|
||||
configLoader = MockConfigLoader()
|
||||
subject = CloudLogoutService(
|
||||
cloudSessionController: cloudSessionController,
|
||||
subject = LabLogoutService(
|
||||
labSessionController: labSessionController,
|
||||
configLoader: configLoader
|
||||
)
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
super.tearDown()
|
||||
cloudSessionController = nil
|
||||
labSessionController = nil
|
||||
configLoader = nil
|
||||
subject = nil
|
||||
}
|
||||
|
@ -62,24 +62,24 @@ final class CloudLogoutServiceTests: TuistUnitTestCase {
|
|||
func test_printSession_when_cloudURL_is_missing() {
|
||||
// Given
|
||||
configLoader.loadConfigStub = { _ in
|
||||
Config.test(cloud: nil)
|
||||
Config.test(lab: nil)
|
||||
}
|
||||
|
||||
// Then
|
||||
XCTAssertThrowsSpecific(try subject.logout(), CloudLogoutServiceError.missingCloudURL)
|
||||
XCTAssertThrowsSpecific(try subject.logout(), LabLogoutServiceError.missingLabURL)
|
||||
}
|
||||
|
||||
func test_printSession() throws {
|
||||
// Given
|
||||
let cloudURL = URL.test()
|
||||
let labURL = URL.test()
|
||||
configLoader.loadConfigStub = { _ in
|
||||
Config.test(cloud: Cloud(url: cloudURL, projectId: "123", options: []))
|
||||
Config.test(lab: Lab(url: labURL, projectId: "123", options: []))
|
||||
}
|
||||
|
||||
// When
|
||||
try subject.logout()
|
||||
|
||||
// Then
|
||||
XCTAssertTrue(cloudSessionController.logoutArgs.contains(cloudURL))
|
||||
XCTAssertTrue(labSessionController.logoutArgs.contains(labURL))
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
import Foundation
|
||||
import TSCBasic
|
||||
import TuistCloudTesting
|
||||
import TuistCore
|
||||
import TuistCoreTesting
|
||||
import TuistGraph
|
||||
import TuistGraphTesting
|
||||
import TuistLabTesting
|
||||
import TuistLoader
|
||||
import TuistLoaderTesting
|
||||
import TuistSupport
|
||||
|
@ -13,21 +13,21 @@ import XCTest
|
|||
@testable import TuistKit
|
||||
@testable import TuistSupportTesting
|
||||
|
||||
final class CloudSessionServiceErrorTests: TuistUnitTestCase {
|
||||
final class LabSessionServiceErrorTests: TuistUnitTestCase {
|
||||
func test_description_when_missingCloudURL() {
|
||||
// Given
|
||||
let subject = CloudSessionServiceError.missingCloudURL
|
||||
let subject = LabSessionServiceError.missingLabURL
|
||||
|
||||
// When
|
||||
let got = subject.description
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, "The cloud URL attribute is missing in your project's configuration.")
|
||||
XCTAssertEqual(got, "The lab URL attribute is missing in your project's configuration.")
|
||||
}
|
||||
|
||||
func test_type_when_missingCloudURL() {
|
||||
// Given
|
||||
let subject = CloudSessionServiceError.missingCloudURL
|
||||
let subject = LabSessionServiceError.missingLabURL
|
||||
|
||||
// When
|
||||
let got = subject.type
|
||||
|
@ -37,24 +37,24 @@ final class CloudSessionServiceErrorTests: TuistUnitTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
final class CloudSessionServiceTests: TuistUnitTestCase {
|
||||
var cloudSessionController: MockCloudSessionController!
|
||||
final class LabSessionServiceTests: TuistUnitTestCase {
|
||||
var labSessionController: MockLabSessionController!
|
||||
var configLoader: MockConfigLoader!
|
||||
var subject: CloudSessionService!
|
||||
var subject: LabSessionService!
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
cloudSessionController = MockCloudSessionController()
|
||||
labSessionController = MockLabSessionController()
|
||||
configLoader = MockConfigLoader()
|
||||
subject = CloudSessionService(
|
||||
cloudSessionController: cloudSessionController,
|
||||
subject = LabSessionService(
|
||||
labSessionController: labSessionController,
|
||||
configLoader: configLoader
|
||||
)
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
super.tearDown()
|
||||
cloudSessionController = nil
|
||||
labSessionController = nil
|
||||
configLoader = nil
|
||||
subject = nil
|
||||
}
|
||||
|
@ -62,24 +62,24 @@ final class CloudSessionServiceTests: TuistUnitTestCase {
|
|||
func test_printSession_when_cloudURL_is_missing() {
|
||||
// Given
|
||||
configLoader.loadConfigStub = { _ in
|
||||
Config.test(cloud: nil)
|
||||
Config.test(lab: nil)
|
||||
}
|
||||
|
||||
// Then
|
||||
XCTAssertThrowsSpecific(try subject.printSession(), CloudSessionServiceError.missingCloudURL)
|
||||
XCTAssertThrowsSpecific(try subject.printSession(), LabSessionServiceError.missingLabURL)
|
||||
}
|
||||
|
||||
func test_printSession() throws {
|
||||
// Given
|
||||
let cloudURL = URL.test()
|
||||
let labURL = URL.test()
|
||||
configLoader.loadConfigStub = { _ in
|
||||
Config.test(cloud: Cloud(url: cloudURL, projectId: "123", options: []))
|
||||
Config.test(lab: Lab(url: labURL, projectId: "123", options: []))
|
||||
}
|
||||
|
||||
// When
|
||||
try subject.printSession()
|
||||
|
||||
// Then
|
||||
XCTAssertTrue(cloudSessionController.printSessionArgs.contains(cloudURL))
|
||||
XCTAssertTrue(labSessionController.printSessionArgs.contains(labURL))
|
||||
}
|
||||
}
|
|
@ -3,13 +3,13 @@ import TSCBasic
|
|||
import TuistSupport
|
||||
import XCTest
|
||||
|
||||
@testable import TuistCloud
|
||||
@testable import TuistLab
|
||||
@testable import TuistSupportTesting
|
||||
|
||||
final class CloudSessionControllerErrorTests: TuistUnitTestCase {
|
||||
final class LabSessionControllerErrorTests: TuistUnitTestCase {
|
||||
func test_description_when_missingParameters() {
|
||||
// Given
|
||||
let subject = CloudSessionControllerError.missingParameters
|
||||
let subject = LabSessionControllerError.missingParameters
|
||||
|
||||
// When
|
||||
let got = subject.description
|
||||
|
@ -20,7 +20,7 @@ final class CloudSessionControllerErrorTests: TuistUnitTestCase {
|
|||
|
||||
func test_type_when_missingParameters() {
|
||||
// Given
|
||||
let subject = CloudSessionControllerError.missingParameters
|
||||
let subject = LabSessionControllerError.missingParameters
|
||||
|
||||
// When
|
||||
let got = subject.type
|
||||
|
@ -31,7 +31,7 @@ final class CloudSessionControllerErrorTests: TuistUnitTestCase {
|
|||
|
||||
func test_description_when_authenticationError() {
|
||||
// Given
|
||||
let subject = CloudSessionControllerError.authenticationError("error")
|
||||
let subject = LabSessionControllerError.authenticationError("error")
|
||||
|
||||
// When
|
||||
let got = subject.description
|
||||
|
@ -42,7 +42,7 @@ final class CloudSessionControllerErrorTests: TuistUnitTestCase {
|
|||
|
||||
func test_type_when_authenticationError() {
|
||||
// Given
|
||||
let subject = CloudSessionControllerError.authenticationError("error")
|
||||
let subject = LabSessionControllerError.authenticationError("error")
|
||||
|
||||
// When
|
||||
let got = subject.type
|
||||
|
@ -53,7 +53,7 @@ final class CloudSessionControllerErrorTests: TuistUnitTestCase {
|
|||
|
||||
func test_description_when_invalidParameters() {
|
||||
// Given
|
||||
let subject = CloudSessionControllerError.invalidParameters(["invalid"])
|
||||
let subject = LabSessionControllerError.invalidParameters(["invalid"])
|
||||
|
||||
// When
|
||||
let got = subject.description
|
||||
|
@ -64,7 +64,7 @@ final class CloudSessionControllerErrorTests: TuistUnitTestCase {
|
|||
|
||||
func test_type_when_invalidParameters() {
|
||||
// Given
|
||||
let subject = CloudSessionControllerError.invalidParameters(["invalid"])
|
||||
let subject = LabSessionControllerError.invalidParameters(["invalid"])
|
||||
|
||||
// When
|
||||
let got = subject.type
|
||||
|
@ -74,13 +74,13 @@ final class CloudSessionControllerErrorTests: TuistUnitTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
final class CloudSessionControllerTests: TuistUnitTestCase {
|
||||
final class LabSessionControllerTests: TuistUnitTestCase {
|
||||
var credentialsStore: MockCredentialsStore!
|
||||
var httpRedirectListener: MockHTTPRedirectListener!
|
||||
var ciChecker: MockCIChecker!
|
||||
var opener: MockOpener!
|
||||
var serverURL: URL!
|
||||
var subject: CloudSessionController!
|
||||
var subject: LabSessionController!
|
||||
|
||||
override func setUp() {
|
||||
credentialsStore = MockCredentialsStore()
|
||||
|
@ -88,7 +88,7 @@ final class CloudSessionControllerTests: TuistUnitTestCase {
|
|||
ciChecker = MockCIChecker()
|
||||
opener = MockOpener()
|
||||
serverURL = URL.test()
|
||||
subject = CloudSessionController(
|
||||
subject = LabSessionController(
|
||||
credentialsStore: credentialsStore,
|
||||
httpRedirectListener: httpRedirectListener,
|
||||
ciChecker: ciChecker,
|
||||
|
@ -110,14 +110,14 @@ final class CloudSessionControllerTests: TuistUnitTestCase {
|
|||
func test_authenticate_when_parametersAreMissing() throws {
|
||||
// Given
|
||||
httpRedirectListener.listenStub = { (port, path, message, _) -> (Swift.Result<[String: String]?, HTTPRedirectListenerError>) in
|
||||
XCTAssertEqual(port, CloudSessionController.port)
|
||||
XCTAssertEqual(port, LabSessionController.port)
|
||||
XCTAssertEqual(path, "auth")
|
||||
XCTAssertEqual(message, "Switch back to your terminal to continue the authentication.")
|
||||
return .success(nil)
|
||||
}
|
||||
|
||||
// Then
|
||||
XCTAssertThrowsSpecific(try subject.authenticate(serverURL: serverURL), CloudSessionControllerError.missingParameters)
|
||||
XCTAssertThrowsSpecific(try subject.authenticate(serverURL: serverURL), LabSessionControllerError.missingParameters)
|
||||
XCTAssertPrinterOutputContains("""
|
||||
Opening \(authURL().absoluteString) to start the authentication flow
|
||||
""")
|
||||
|
@ -126,14 +126,14 @@ final class CloudSessionControllerTests: TuistUnitTestCase {
|
|||
func test_authenticate_when_parametersIncludeError() throws {
|
||||
// Given
|
||||
httpRedirectListener.listenStub = { (port, path, message, _) -> (Swift.Result<[String: String]?, HTTPRedirectListenerError>) in
|
||||
XCTAssertEqual(port, CloudSessionController.port)
|
||||
XCTAssertEqual(port, LabSessionController.port)
|
||||
XCTAssertEqual(path, "auth")
|
||||
XCTAssertEqual(message, "Switch back to your terminal to continue the authentication.")
|
||||
return .success(["error": "value"])
|
||||
}
|
||||
|
||||
// Then
|
||||
XCTAssertThrowsSpecific(try subject.authenticate(serverURL: serverURL), CloudSessionControllerError.authenticationError("value"))
|
||||
XCTAssertThrowsSpecific(try subject.authenticate(serverURL: serverURL), LabSessionControllerError.authenticationError("value"))
|
||||
XCTAssertPrinterOutputContains("""
|
||||
Opening \(authURL().absoluteString) to start the authentication flow
|
||||
""")
|
||||
|
@ -142,7 +142,7 @@ final class CloudSessionControllerTests: TuistUnitTestCase {
|
|||
func test_authenticate_when_tokenAndAccountParametersAreIncluded() throws {
|
||||
// Given
|
||||
httpRedirectListener.listenStub = { (port, path, message, _) -> (Swift.Result<[String: String]?, HTTPRedirectListenerError>) in
|
||||
XCTAssertEqual(port, CloudSessionController.port)
|
||||
XCTAssertEqual(port, LabSessionController.port)
|
||||
XCTAssertEqual(path, "auth")
|
||||
XCTAssertEqual(message, "Switch back to your terminal to continue the authentication.")
|
||||
return .success(["account": "account", "token": "token"])
|
||||
|
@ -164,14 +164,14 @@ final class CloudSessionControllerTests: TuistUnitTestCase {
|
|||
func test_authenticate_when_parametersContainInvalidKeys() throws {
|
||||
// Given
|
||||
httpRedirectListener.listenStub = { (port, path, message, _) -> (Swift.Result<[String: String]?, HTTPRedirectListenerError>) in
|
||||
XCTAssertEqual(port, CloudSessionController.port)
|
||||
XCTAssertEqual(port, LabSessionController.port)
|
||||
XCTAssertEqual(path, "auth")
|
||||
XCTAssertEqual(message, "Switch back to your terminal to continue the authentication.")
|
||||
return .success(["invalid": "value"])
|
||||
}
|
||||
|
||||
// Then
|
||||
XCTAssertThrowsSpecific(try subject.authenticate(serverURL: serverURL), CloudSessionControllerError.invalidParameters(["invalid"]))
|
||||
XCTAssertThrowsSpecific(try subject.authenticate(serverURL: serverURL), LabSessionControllerError.invalidParameters(["invalid"]))
|
||||
XCTAssertPrinterOutputContains("""
|
||||
Opening \(authURL().absoluteString) to start the authentication flow
|
||||
""")
|
|
@ -3,20 +3,20 @@ import TSCBasic
|
|||
import TuistSupport
|
||||
import XCTest
|
||||
|
||||
@testable import TuistCloud
|
||||
@testable import TuistLab
|
||||
@testable import TuistSupportTesting
|
||||
|
||||
final class CloudHTTPRequestAuthenticatorTests: TuistUnitTestCase {
|
||||
final class LabHTTPRequestAuthenticatorTests: TuistUnitTestCase {
|
||||
var ciChecker: MockCIChecker!
|
||||
var credentialsStore: MockCredentialsStore!
|
||||
var subject: CloudHTTPRequestAuthenticator!
|
||||
var subject: LabHTTPRequestAuthenticator!
|
||||
var environmentVariables: [String: String] = [:]
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
ciChecker = MockCIChecker()
|
||||
credentialsStore = MockCredentialsStore()
|
||||
subject = CloudHTTPRequestAuthenticator(
|
||||
subject = LabHTTPRequestAuthenticator(
|
||||
ciChecker: ciChecker,
|
||||
environmentVariables: { self.environmentVariables },
|
||||
credentialsStore: credentialsStore
|
||||
|
@ -34,8 +34,8 @@ final class CloudHTTPRequestAuthenticatorTests: TuistUnitTestCase {
|
|||
// Given
|
||||
ciChecker.isCIStub = true
|
||||
let token = "TOKEN"
|
||||
environmentVariables[Constants.EnvironmentVariables.cloudToken] = token
|
||||
let request = URLRequest(url: URL(string: "https://cloud.tuist.io/path")!)
|
||||
environmentVariables[Constants.EnvironmentVariables.labToken] = token
|
||||
let request = URLRequest(url: URL(string: "https://lab.tuist.io/path")!)
|
||||
|
||||
// When
|
||||
let got = try subject.authenticate(request: request)
|
||||
|
@ -49,8 +49,8 @@ final class CloudHTTPRequestAuthenticatorTests: TuistUnitTestCase {
|
|||
ciChecker.isCIStub = false
|
||||
let token = "TOKEN"
|
||||
let credentials = Credentials(token: token, account: "test")
|
||||
try credentialsStore.store(credentials: credentials, serverURL: URL(string: "https://cloud.tuist.io")!)
|
||||
let request = URLRequest(url: URL(string: "https://cloud.tuist.io/path")!)
|
||||
try credentialsStore.store(credentials: credentials, serverURL: URL(string: "https://lab.tuist.io")!)
|
||||
let request = URLRequest(url: URL(string: "https://lab.tuist.io/path")!)
|
||||
|
||||
// When
|
||||
let got = try subject.authenticate(request: request)
|
|
@ -74,7 +74,7 @@ final class ConfigLoaderTests: TuistUnitTestCase {
|
|||
// Then
|
||||
XCTAssertEqual(result, TuistGraph.Config(
|
||||
compatibleXcodeVersions: .all,
|
||||
cloud: nil,
|
||||
lab: nil,
|
||||
cache: nil,
|
||||
plugins: [],
|
||||
generationOptions: [.developmentRegion("fr")],
|
||||
|
@ -116,7 +116,7 @@ final class ConfigLoaderTests: TuistUnitTestCase {
|
|||
// Then
|
||||
XCTAssertEqual(result, TuistGraph.Config(
|
||||
compatibleXcodeVersions: .all,
|
||||
cloud: nil,
|
||||
lab: nil,
|
||||
cache: nil,
|
||||
plugins: [],
|
||||
generationOptions: [.developmentRegion("fr")],
|
||||
|
|
|
@ -244,7 +244,7 @@ final class PluginServiceTests: TuistTestCase {
|
|||
private func mockConfig(plugins: [TuistGraph.PluginLocation]) -> TuistGraph.Config {
|
||||
Config(
|
||||
compatibleXcodeVersions: .all,
|
||||
cloud: nil,
|
||||
lab: nil,
|
||||
cache: nil,
|
||||
plugins: plugins,
|
||||
generationOptions: [],
|
||||
|
|
Loading…
Reference in New Issue