Cloud to lab (#2993)

This commit is contained in:
Pedro Piñera Buendía 2021-05-22 09:58:02 +02:00 committed by GitHub
parent 49761cbd7c
commit 6e58ef29d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
66 changed files with 458 additions and 455 deletions

View File

@ -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,

View File

@ -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)
}
}

View File

@ -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)
}

View File

@ -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)
}
}

View File

@ -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)

View File

@ -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")

View File

@ -1 +0,0 @@
struct CloudHEADResponse: Decodable {}

View File

@ -1,3 +0,0 @@
struct CloudVerifyUploadResponse: Decodable {
let uploadedSize: Int
}

View File

@ -1,6 +1,6 @@
import Foundation
struct CloudCacheResponse: Decodable {
struct LabCacheResponse: Decodable {
let url: URL
let expiresAt: TimeInterval

View File

@ -0,0 +1,3 @@
import Foundation
struct LabHEADResponse: Decodable {}

View File

@ -0,0 +1,5 @@
import Foundation
struct LabVerifyUploadResponse: Decodable {
let uploadedSize: Int
}

View File

@ -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)

View File

@ -1,7 +0,0 @@
@testable import TuistCache
extension CloudVerifyUploadResponse {
public static func test(uploadedSize: Int = 0) -> CloudVerifyUploadResponse {
CloudVerifyUploadResponse(uploadedSize: uploadedSize)
}
}

View File

@ -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
)

View File

@ -0,0 +1,7 @@
@testable import TuistCache
extension LabVerifyUploadResponse {
public static func test(uploadedSize: Int = 0) -> LabVerifyUploadResponse {
LabVerifyUploadResponse(uploadedSize: uploadedSize)
}
}

View File

@ -1,2 +0,0 @@
import TuistSupport
let logger = Logger(label: "io.tuist.cloud")

View File

@ -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)>
}

View File

@ -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

View File

@ -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() {}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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

View File

@ -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) }
}
}

View File

@ -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)
}

View File

@ -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

View File

@ -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,

View File

@ -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)
}
}

View File

@ -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

View File

@ -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

View File

@ -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,
]
)
}
}

View File

@ -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()
}
}

View File

@ -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()
}
}

View File

@ -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()
}
}

View File

@ -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,
]
)
}
}

View File

@ -25,7 +25,7 @@ public struct TuistCommand: ParsableCommand {
CreateIssueCommand.self,
ScaffoldCommand.self,
InitCommand.self,
CloudCommand.self,
LabCommand.self,
CacheCommand.self,
SigningCommand.self,
MigrationCommand.self,

View File

@ -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.

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}
}

View File

@ -1,6 +1,6 @@
import Foundation
public enum CloudClientError: LocalizedError, Equatable {
public enum LabClientError: LocalizedError, Equatable {
case unauthorized
public var errorDescription: String? {

View File

@ -0,0 +1,2 @@
import TuistSupport
let logger = Logger(label: "io.tuist.lab")

View File

@ -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))
}
}
}

View File

@ -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
}

View File

@ -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] = []

View File

@ -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)?

View File

@ -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

View File

@ -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,

View File

@ -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"
}

View File

@ -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"),

View File

@ -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)
}
}

View File

@ -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 }

View File

@ -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"),

View File

@ -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 {

View File

@ -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)
}

View File

@ -1,9 +1,9 @@
import Foundation
import TuistCache
import TuistCloud
import TuistCore
import TuistCoreTesting
import TuistGenerator
import TuistLab
import TuistSigning
import TuistSupport
import XCTest

View File

@ -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

View File

@ -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

View File

@ -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))
}
}

View File

@ -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))
}
}

View File

@ -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))
}
}

View File

@ -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
""")

View File

@ -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)

View File

@ -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")],

View File

@ -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: [],