Skip to content

Commit

Permalink
Add support for CocoaPods dependencies (#465)
Browse files Browse the repository at this point in the history
* Add TargetDependency.cocoapods

* Add Dependency.cocoapods

* Add CocoaPodsNode model and support for caching it to the GraphLoaderCache

* Add tests to CocoaPodsNode

* Support loading a CocoaPods target dependency

* Test TargetNode changes

* Lint that the directories referenced by CocoaPods dependencies contain a Podfile

* Run 'pod install' after the workspace generation

* Add documentation

* Update Pod specs repository automtically

* Update CHANGELOG

* Add acceptance tests

* Remove empty code block and fix acceptance test
  • Loading branch information
Pedro Piñera Buendía committed Aug 4, 2019
1 parent a3684c6 commit 2285432
Show file tree
Hide file tree
Showing 41 changed files with 897 additions and 66 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Please, check out guidelines: https://keepachangelog.com/en/1.0.0/
- Support multiple header paths https://github.com/tuist/tuist/pull/459 by @adamkhazi
- Allow specifying multiple configurations within project manifests https://github.com/tuist/tuist/pull/451 by @kwridan
- Add linting for mismatching build configurations in a workspace https://github.com/tuist/tuist/pull/474 by @kwridan
- Support for CocoaPods dependencies https://github.com/tuist/tuist/pull/465 by @pepibumur

### Fixed

Expand Down
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ gem "danger-swiftlint", "~> 0.23.0"
gem "encrypted-environment", "~> 0.2.0"
gem "google-cloud-storage", "~> 1.19"
gem "colorize", "~> 0.8.1"
gem "cocoapods", "~> 1.7"
62 changes: 61 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,59 @@ GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.0)
activesupport (4.2.11.1)
i18n (~> 0.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
ast (2.4.0)
atomos (0.1.3)
backports (3.11.4)
builder (3.2.3)
byebug (10.0.2)
claide (1.0.2)
claide (1.0.3)
claide-plugins (0.9.2)
cork
nap
open4 (~> 1.3)
cocoapods (1.7.5)
activesupport (>= 4.0.2, < 5)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.7.5)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
cocoapods-downloader (>= 1.2.2, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-stats (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.3.1, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
fourflusher (>= 2.3.0, < 3.0)
gh_inspector (~> 1.0)
molinillo (~> 0.6.6)
nap (~> 1.0)
ruby-macho (~> 1.4)
xcodeproj (>= 1.10.0, < 2.0)
cocoapods-core (1.7.5)
activesupport (>= 4.0.2, < 6)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
cocoapods-deintegrate (1.0.4)
cocoapods-downloader (1.2.2)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.0)
cocoapods-stats (1.1.0)
cocoapods-trunk (1.3.1)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.1.0)
colored2 (3.1.2)
colorize (0.8.1)
concurrent-ruby (1.1.5)
cork (0.3.0)
colored2 (~> 3.1)
cucumber (3.1.2)
Expand Down Expand Up @@ -64,10 +104,14 @@ GEM
ejson (1.2.1)
encrypted-environment (0.2.0)
ejson (~> 1.2)
escape (0.0.4)
faraday (0.15.4)
multipart-post (>= 1.2, < 3)
faraday-http-cache (2.0.0)
faraday (~> 0.8)
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
gherkin (5.1.0)
git (1.5.0)
google-api-client (0.30.5)
Expand Down Expand Up @@ -97,6 +141,8 @@ GEM
os (>= 0.9, < 2.0)
signet (~> 0.7)
httpclient (2.8.3)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
jaro_winkler (1.5.3)
jwt (2.2.1)
kramdown (2.1.0)
Expand All @@ -108,11 +154,14 @@ GEM
mime-types-data (3.2019.0331)
mini_mime (1.0.2)
minitest (5.11.3)
molinillo (0.6.6)
multi_json (1.13.1)
multi_test (0.1.2)
multipart-post (2.1.1)
nanaimo (0.2.6)
nap (1.1.0)
naturally (2.2.0)
netrc (0.11.0)
no_proxy_fix (0.1.2)
octokit (4.14.0)
sawyer (~> 0.8.0, >= 0.5.3)
Expand All @@ -136,6 +185,7 @@ GEM
rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 1.7)
ruby-macho (1.4.0)
ruby-progressbar (1.10.1)
sawyer (0.8.2)
addressable (>= 2.3.5)
Expand All @@ -151,14 +201,24 @@ GEM
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thor (0.20.3)
thread_safe (0.3.6)
tzinfo (1.2.5)
thread_safe (~> 0.1)
uber (0.1.0)
unicode-display_width (1.6.0)
xcodeproj (1.12.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.2.6)

PLATFORMS
ruby

DEPENDENCIES
byebug (~> 10.0)
cocoapods (~> 1.7)
colorize (~> 0.8.1)
cucumber (~> 3.1)
danger (~> 6.0)
Expand Down
13 changes: 13 additions & 0 deletions Sources/ProjectDescription/TargetDependency.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ public enum TargetDependency: Codable, Equatable {
/// - status: The dependency status (optional dependencies are weakly linked)
case sdk(name: String, status: SDKStatus)

/// Dependency on CocoaPods pods.
///
/// - Parameters:
/// - path: Path to the directory that contains the Podfile.
case cocoapods(path: String)

/// Dependency on system library or framework
///
/// - Parameters:
Expand All @@ -71,6 +77,8 @@ public enum TargetDependency: Codable, Equatable {
return "library"
case .sdk:
return "sdk"
case .cocoapods:
return "cocoapods"
}
}
}
Expand Down Expand Up @@ -125,6 +133,9 @@ extension TargetDependency {
self = .sdk(name: try container.decode(String.self, forKey: .name),
status: try container.decode(SDKStatus.self, forKey: .status))

case "cocoapods":
self = .cocoapods(path: try container.decode(String.self, forKey: .path))

default:
throw CodingError.unknownType(type)
}
Expand All @@ -150,6 +161,8 @@ extension TargetDependency {
case let .sdk(name, status):
try container.encode(name, forKey: .name)
try container.encode(status, forKey: .status)
case let .cocoapods(path):
try container.encode(path, forKey: .path)
}
}
}
8 changes: 4 additions & 4 deletions Sources/TuistCore/Utils/Printer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ public class Printer: Printing {

public func print(error: Error) {
let writer = InteractiveWriter.stderr
writer.write("Error: ", inColor: .red, bold: true)
writer.write("Error: ", inColor: .red, bold: true)
writer.write(error.localizedDescription)
writer.write("\n")
}

public func print(success: String) {
let writer = InteractiveWriter.stdout
writer.write("Success: ", inColor: .green, bold: true)
writer.write("Success: ", inColor: .green, bold: true)
writer.write(success)
writer.write("\n")
}
Expand All @@ -62,14 +62,14 @@ public class Printer: Printing {

public func print(warning: String) {
let writer = InteractiveWriter.stdout
writer.write("⚠️ Warning: ", inColor: .yellow, bold: true)
writer.write("Warning: ", inColor: .yellow, bold: true)
writer.write(warning, inColor: .yellow, bold: false)
writer.write("\n")
}

public func print(errorMessage: String) {
let writer = InteractiveWriter.stderr
writer.write("Error: ", inColor: .red, bold: true)
writer.write("Error: ", inColor: .red, bold: true)
writer.write(errorMessage, inColor: .red, bold: false)
writer.write("\n")
}
Expand Down
31 changes: 29 additions & 2 deletions Sources/TuistCore/Utils/System.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,16 @@ public protocol Systeming {
/// - Throws: An error if the command fails.
func runAndPrint(_ arguments: [String], verbose: Bool, environment: [String: String]) throws

/// Runs a command in the shell printing its output.
///
/// - Parameters:
/// - arguments: Command.
/// - verbose: When true it prints the command that will be executed before executing it.
/// - environment: Environment that should be used when running the task.
/// - redirection: Instance through which the output will be redirected.
/// - Throws: An error if the command fails.
func runAndPrint(_ arguments: [String], verbose: Bool, environment: [String: String], redirection: Basic.Process.OutputRedirection) throws

/// Runs a command in the shell asynchronously.
/// When the process that triggers the command gets killed, the command continues its execution.
///
Expand Down Expand Up @@ -283,7 +293,6 @@ public final class System: Systeming {
/// - Parameters:
/// - arguments: Arguments to be passed.
/// - verbose: When true it prints the command that will be executed before executing it.
/// - workingDirectoryPath: The working directory path the task is executed from.
/// - environment: Environment that should be used when running the task.
/// - Throws: An error if the command fails.
public func runAndPrint(_ arguments: String...,
Expand All @@ -304,16 +313,34 @@ public final class System: Systeming {
public func runAndPrint(_ arguments: [String],
verbose: Bool,
environment: [String: String]) throws {
try runAndPrint(arguments,
verbose: verbose,
environment: environment,
redirection: .none)
}

/// Runs a command in the shell printing its output.
///
/// - Parameters:
/// - arguments: Command.
/// - verbose: When true it prints the command that will be executed before executing it.
/// - environment: Environment that should be used when running the task.
/// - redirection: Instance through which the output will be redirected.
/// - Throws: An error if the command fails.
public func runAndPrint(_ arguments: [String], verbose: Bool, environment: [String: String], redirection: Basic.Process.OutputRedirection) throws {
let process = Process(arguments: arguments,
environment: environment,
outputRedirection: .stream(stdout: { bytes in
FileHandle.standardOutput.write(Data(bytes))
redirection.outputClosures?.stdoutClosure(bytes)
}, stderr: { bytes in
FileHandle.standardError.write(Data(bytes))
redirection.outputClosures?.stderrClosure(bytes)
}), verbose: verbose,
startNewProcessGroup: false)
try process.launch()
try process.waitUntilExit()
let result = try process.waitUntilExit()
try result.throwIfErrored()
}

/// Runs a command in the shell asynchronously.
Expand Down
31 changes: 19 additions & 12 deletions Sources/TuistCoreTesting/Utils/MockSystem.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import struct Basic.AbsolutePath
import Basic
import Foundation
import TuistCore

Expand All @@ -13,15 +13,15 @@ public final class MockSystem: Systeming {
public init() {}

public func errorCommand(_ arguments: String..., error: String? = nil) {
self.errorCommand(arguments, error: error)
errorCommand(arguments, error: error)
}

public func errorCommand(_ arguments: [String], error: String? = nil) {
stubs[arguments.joined(separator: " ")] = (stderror: error, stdout: nil, exitstatus: 1)
}

public func succeedCommand(_ arguments: String..., output: String? = nil) {
self.succeedCommand(arguments, output: output)
succeedCommand(arguments, output: output)
}

public func succeedCommand(_ arguments: [String], output: String? = nil) {
Expand All @@ -39,19 +39,19 @@ public final class MockSystem: Systeming {
}

public func run(_ arguments: String...) throws {
try self.run(arguments)
try run(arguments)
}

public func capture(_ arguments: [String]) throws -> String {
return try self.capture(arguments, verbose: false, environment: [:])
return try capture(arguments, verbose: false, environment: [:])
}

public func capture(_ arguments: String...) throws -> String {
return try self.capture(arguments, verbose: false, environment: [:])
return try capture(arguments, verbose: false, environment: [:])
}

public func capture(_ arguments: String..., verbose: Bool, environment: [String: String]) throws -> String {
return try self.capture(arguments, verbose: verbose, environment: environment)
return try capture(arguments, verbose: verbose, environment: environment)
}

public func capture(_ arguments: [String], verbose _: Bool, environment _: [String: String]) throws -> String {
Expand All @@ -66,29 +66,36 @@ public final class MockSystem: Systeming {
}

public func runAndPrint(_ arguments: String...) throws {
try self.runAndPrint(arguments)
try runAndPrint(arguments)
}

public func runAndPrint(_ arguments: [String]) throws {
try self.runAndPrint(arguments, verbose: false, environment: [:])
try runAndPrint(arguments, verbose: false, environment: [:])
}

public func runAndPrint(_ arguments: String..., verbose: Bool, environment: [String: String]) throws {
try self.runAndPrint(arguments, verbose: verbose, environment: environment)
try runAndPrint(arguments, verbose: verbose, environment: environment)
}

public func runAndPrint(_ arguments: [String], verbose _: Bool, environment _: [String: String]) throws {
public func runAndPrint(_ arguments: [String], verbose: Bool, environment: [String: String]) throws {
try runAndPrint(arguments, verbose: verbose, environment: environment, redirection: .none)
}

public func runAndPrint(_ arguments: [String], verbose _: Bool, environment _: [String: String], redirection: Basic.Process.OutputRedirection) throws {
let command = arguments.joined(separator: " ")
guard let stub = self.stubs[command] else {
throw SystemError.terminated(code: 1, error: "command '\(command)' not stubbed")
}
if stub.exitstatus != 0 {
if let error = stub.stderror {
redirection.outputClosures?.stderrClosure([UInt8](error.data(using: .utf8)!))
}
throw SystemError.terminated(code: 1, error: stub.stderror ?? "")
}
}

public func async(_ arguments: [String]) throws {
try self.async(arguments, verbose: false, environment: [:])
try async(arguments, verbose: false, environment: [:])
}

public func async(_ arguments: [String], verbose _: Bool, environment _: [String: String]) throws {
Expand Down
4 changes: 3 additions & 1 deletion Sources/TuistGenerator/Generator/Generator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,13 @@ public class Generator: Generating {
system: system,
fileHandler: fileHandler)
let workspaceStructureGenerator = WorkspaceStructureGenerator(fileHandler: fileHandler)
let cocoapodsInteractor = CocoaPodsInteractor()
let workspaceGenerator = WorkspaceGenerator(system: system,
printer: printer,
projectGenerator: projectGenerator,
fileHandler: fileHandler,
workspaceStructureGenerator: workspaceStructureGenerator)
workspaceStructureGenerator: workspaceStructureGenerator,
cocoapodsInteractor: cocoapodsInteractor)
self.init(graphLoader: graphLoader,
workspaceGenerator: workspaceGenerator,
projectGenerator: projectGenerator)
Expand Down

0 comments on commit 2285432

Please sign in to comment.