-
-
Notifications
You must be signed in to change notification settings - Fork 505
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add compatible Xcodes option to the TuistConfig (#476)
* Add model changes to ProjectDescription * Add models to the TuistGenerator target * Create Xcode & XcodeController to interact with local Xcode installations * Implement TuistConfigLinter * Add acceptance test * Support initializing CompatibleXcodeVersions with a string literal * Add documentation * Update CHANGELOG * Address comments * Fix imports * Rename TuistConfigLinter to EnvironmentLinter * Some style fixes
- Loading branch information
Pedro Piñera Buendía
committed
Aug 7, 2019
1 parent
1aed58f
commit 2b09f5c
Showing
37 changed files
with
774 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import Foundation | ||
|
||
/// Enum that represents all the Xcode versions that a project or set of projects is compatible with. | ||
public enum CompatibleXcodeVersions: ExpressibleByArrayLiteral, ExpressibleByStringLiteral, Codable, Equatable { | ||
/// The project supports all Xcode versions. | ||
case all | ||
|
||
/// List of versions that are supported by the project. | ||
case list([String]) | ||
|
||
// MARK: - ExpressibleByArrayLiteral | ||
|
||
public init(arrayLiteral elements: [String]) { | ||
self = .list(elements) | ||
} | ||
|
||
public init(arrayLiteral elements: String...) { | ||
self = .list(elements) | ||
} | ||
|
||
enum CodignKeys: String, CodingKey { | ||
case type | ||
case value | ||
} | ||
|
||
// MARK: - ExpressibleByStringLiteral | ||
|
||
public init(stringLiteral value: String) { | ||
self = .list([value]) | ||
} | ||
|
||
// MARK: - Codable | ||
|
||
public func encode(to encoder: Encoder) throws { | ||
var container = encoder.container(keyedBy: CodignKeys.self) | ||
switch self { | ||
case .all: | ||
try container.encode("all", forKey: .type) | ||
case let .list(versions): | ||
try container.encode("list", forKey: .type) | ||
try container.encode(versions, forKey: .value) | ||
} | ||
} | ||
|
||
public init(from decoder: Decoder) throws { | ||
let container = try decoder.container(keyedBy: CodignKeys.self) | ||
let type = try container.decode(String.self, forKey: .type) | ||
|
||
switch type { | ||
case "all": | ||
self = .all | ||
case "list": | ||
self = .list(try container.decode([String].self, forKey: .value)) | ||
default: | ||
throw DecodingError.dataCorruptedError(forKey: CodignKeys.type, in: container, debugDescription: "Invalid type \(type)") | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import Basic | ||
import Foundation | ||
|
||
public struct Xcode { | ||
/// It represents the content of the Info.plist file inside the Xcode app bundle. | ||
public struct InfoPlist: Codable { | ||
/// App version number (e.g. 10.3) | ||
public let version: String | ||
|
||
/// Initializes the InfoPlist object with its attributes. | ||
/// | ||
/// - Parameter version: Version. | ||
public init(version: String) { | ||
self.version = version | ||
} | ||
|
||
enum CodingKeys: String, CodingKey { | ||
case version = "CFBundleShortVersionString" | ||
} | ||
} | ||
|
||
/// Path to the Xcode app bundle. | ||
public let path: AbsolutePath | ||
|
||
/// Info plist content. | ||
public let infoPlist: InfoPlist | ||
|
||
/// Initializes an Xcode instance by reading it from a local Xcode.app bundle. | ||
/// | ||
/// - Parameter path: Path to a local Xcode.app bundle. | ||
/// - Returns: Initialized Xcode instance. | ||
/// - Throws: An error if the local installation can't be read. | ||
static func read(path: AbsolutePath) throws -> Xcode { | ||
let infoPlistPath = path.appending(RelativePath("Contents/Info.plist")) | ||
let plistDecoder = PropertyListDecoder() | ||
let data = try Data(contentsOf: infoPlistPath.url) | ||
let infoPlist = try plistDecoder.decode(InfoPlist.self, from: data) | ||
|
||
return Xcode(path: path, infoPlist: infoPlist) | ||
} | ||
|
||
/// Initializes an instance of Xcode which represents a local installation of Xcode | ||
/// | ||
/// - Parameters: | ||
/// - path: Path to the Xcode app bundle. | ||
public init(path: AbsolutePath, | ||
infoPlist: InfoPlist) { | ||
self.path = path | ||
self.infoPlist = infoPlist | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import Basic | ||
import Foundation | ||
|
||
public protocol XcodeControlling { | ||
/// Returns the selected Xcode. It uses xcode-select to determine | ||
/// the Xcode that is selected in the environment. | ||
/// | ||
/// - Returns: Selected Xcode. | ||
/// - Throws: An error if it can't be obtained. | ||
func selected() throws -> Xcode? | ||
} | ||
|
||
public class XcodeController: XcodeControlling { | ||
/// Instance to run commands in the system. | ||
let system: Systeming | ||
|
||
/// Initializes the controller with its attributes | ||
/// | ||
/// - Parameters: | ||
/// - system: Instance to run commands in the system. | ||
public init(system: Systeming = System()) { | ||
self.system = system | ||
} | ||
|
||
/// Returns the selected Xcode. It uses xcode-select to determine | ||
/// the Xcode that is selected in the environment. | ||
/// | ||
/// - Returns: Selected Xcode. | ||
/// - Throws: An error if it can't be obtained. | ||
public func selected() throws -> Xcode? { | ||
// e.g. /Applications/Xcode.app/Contents/Developer | ||
guard let path = try? system.capture(["xcode-select", "-p"]).spm_chomp() else { | ||
return nil | ||
} | ||
return try Xcode.read(path: AbsolutePath(path).parentDirectory.parentDirectory) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
Sources/TuistCoreTesting/Xcode/Mocks/MockXcodeController.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import Foundation | ||
|
||
import TuistCore | ||
|
||
final class MockXcodeController: XcodeControlling { | ||
var selectedStub: Result<Xcode, Error>? | ||
|
||
func selected() throws -> Xcode? { | ||
guard let selectedStub = selectedStub else { return nil } | ||
|
||
switch selectedStub { | ||
case let .failure(error): throw error | ||
case let .success(xcode): return xcode | ||
} | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
Sources/TuistCoreTesting/Xcode/TestData/Xcode+TestData.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import Basic | ||
import Foundation | ||
|
||
import TuistCore | ||
|
||
extension Xcode { | ||
static func test(path: AbsolutePath = AbsolutePath("/Applications/Xcode.app"), | ||
infoPlist: Xcode.InfoPlist = .test()) -> Xcode { | ||
return Xcode(path: path, infoPlist: infoPlist) | ||
} | ||
} | ||
|
||
extension Xcode.InfoPlist { | ||
static func test(version: String = "3.2.1") -> Xcode.InfoPlist { | ||
return Xcode.InfoPlist(version: version) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.