Fix missing target dependencies
This commit is contained in:
parent
30021ad864
commit
84595c7025
|
@ -9,6 +9,10 @@ Please, check out guidelines: https://keepachangelog.com/en/1.0.0/
|
|||
- Install command https://github.com/tuist/tuist/pull/83 by @pepibumur.
|
||||
- `--help-env` command to tuistenv by @pepibumur.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix missing target dependencies by @pepibumur.
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Added
|
||||
|
|
|
@ -5,7 +5,7 @@ import Foundation
|
|||
public class Workspace: Codable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case name
|
||||
case projects = "project"
|
||||
case projects
|
||||
}
|
||||
|
||||
public let name: String
|
||||
|
|
|
@ -10,6 +10,6 @@ public class Constants {
|
|||
|
||||
public struct Manifest {
|
||||
public static let project = "Project.swift"
|
||||
public static let workspace = "Woskspace.swift"
|
||||
public static let workspace = "Workspace.swift"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,19 +3,7 @@ import Foundation
|
|||
import TuistCore
|
||||
import xcodeproj
|
||||
|
||||
/// Interface for targets generation.
|
||||
protocol TargetGenerating: AnyObject {
|
||||
/// Generates the manifests target.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - project: Project spec.
|
||||
/// - pbxproj: PBXProj instance from the generated Xcode project.
|
||||
/// - pbxProject: PBXProject instance from the generated project.
|
||||
/// - groups: Project groups.
|
||||
/// - sourceRootPath: Path to the folder that contains the project that is getting generated.
|
||||
/// - context: generation context.
|
||||
/// - options: Generation options.
|
||||
/// - Throws: an error if the generation fails.
|
||||
func generateManifestsTarget(project: Project,
|
||||
pbxproj: PBXProj,
|
||||
pbxProject: PBXProject,
|
||||
|
@ -24,20 +12,6 @@ protocol TargetGenerating: AnyObject {
|
|||
context: GeneratorContexting,
|
||||
options: GenerationOptions) throws
|
||||
|
||||
/// Generates a native target.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - target: Target spec.
|
||||
/// - objects: Xcode project objects.
|
||||
/// - pbxProject: PBXProject instance from the generated project.
|
||||
/// - groups: Project groups.
|
||||
/// - fileElements: Project file elements.
|
||||
/// - sourceRootPath: Path to the folder that contains the project that is getting generated.
|
||||
/// - context: generation context.
|
||||
/// - path: Path to the folder that contains the project manifest.
|
||||
/// - sourceRootPath: Path to the folder that contains the Xcode project that is generated.
|
||||
/// - options: Generation options.
|
||||
/// - Returns: native target.
|
||||
func generateTarget(target targetSpec: Target,
|
||||
objects: PBXObjects,
|
||||
pbxProject: PBXProject,
|
||||
|
@ -48,45 +22,24 @@ protocol TargetGenerating: AnyObject {
|
|||
sourceRootPath: AbsolutePath,
|
||||
options: GenerationOptions) throws -> PBXNativeTarget
|
||||
|
||||
/// Generates the targets dependencies.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - path: path to the folder where the project manifest is.
|
||||
/// - targets: project targets specs.
|
||||
/// - nativeTargets: generated native targes in the Xcode project.
|
||||
/// - objects: Xcode project objects.
|
||||
/// - graph: dependencies graph.
|
||||
/// - Throws: an error if it fails generating the target dependencies.
|
||||
func generateTargetDependencies(path: AbsolutePath,
|
||||
targets: [Target],
|
||||
nativeTargets: [String: PBXNativeTarget],
|
||||
graph: Graphing) throws
|
||||
}
|
||||
|
||||
/// Target generator.
|
||||
final class TargetGenerator: TargetGenerating {
|
||||
/// Config generator.
|
||||
|
||||
// MARK: - Attributes
|
||||
|
||||
let configGenerator: ConfigGenerating
|
||||
|
||||
/// Build phase generator.
|
||||
let buildPhaseGenerator: BuildPhaseGenerating
|
||||
|
||||
/// Link generator.
|
||||
let linkGenerator: LinkGenerating
|
||||
|
||||
/// File generator.
|
||||
let fileGenerator: FileGenerating
|
||||
|
||||
/// Module loader.
|
||||
let moduleLoader: GraphModuleLoading
|
||||
|
||||
/// Initializes the target generator with its attributes.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - configGenerator: config generator.
|
||||
/// - fileGenerator: file generator.
|
||||
/// - buildPhaseGenerator: build phase generator.
|
||||
/// - linkGenerator: link generator.
|
||||
// MARK: - Init
|
||||
|
||||
init(configGenerator: ConfigGenerating = ConfigGenerator(),
|
||||
fileGenerator: FileGenerating = FileGenerator(),
|
||||
buildPhaseGenerator: BuildPhaseGenerating = BuildPhaseGenerator(),
|
||||
|
@ -99,16 +52,8 @@ final class TargetGenerator: TargetGenerating {
|
|||
self.linkGenerator = linkGenerator
|
||||
}
|
||||
|
||||
/// Generates the manifests target.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - project: Project spec.
|
||||
/// - pbxproj: PBXProj instance from the generated Xcode project.
|
||||
/// - pbxProject: PBXProject instance from the generated project.
|
||||
/// - groups: Project groups.
|
||||
/// - sourceRootPath: Path to the folder that contains the project that is getting generated.
|
||||
/// - context: generation context.
|
||||
/// - options: generation options.
|
||||
// MARK: - TargetGenerating
|
||||
|
||||
func generateManifestsTarget(project: Project,
|
||||
pbxproj: PBXProj,
|
||||
pbxProject: PBXProject,
|
||||
|
@ -158,20 +103,6 @@ final class TargetGenerator: TargetGenerating {
|
|||
pbxProject.targetsReferences.append(targetReference)
|
||||
}
|
||||
|
||||
/// Generates a native target.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - target: Target spec.
|
||||
/// - objects: Xcode project objects.
|
||||
/// - pbxProject: PBXProject instance from the generated project.
|
||||
/// - groups: Project groups.
|
||||
/// - fileElements: Project file elements.
|
||||
/// - sourceRootPath: Path to the folder that contains the project that is getting generated.
|
||||
/// - context: generation context.
|
||||
/// - path: Path to the folder that contains the project manifest.
|
||||
/// - sourceRootPath: path to the folder where the Xcode project is generated.
|
||||
/// - options: Generation options.
|
||||
/// - Returns: native target.
|
||||
func generateTarget(target: Target,
|
||||
objects: PBXObjects,
|
||||
pbxProject: PBXProject,
|
||||
|
@ -222,15 +153,6 @@ final class TargetGenerator: TargetGenerating {
|
|||
return pbxTarget
|
||||
}
|
||||
|
||||
/// Generates the targets dependencies.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - path: path to the folder where the project manifest is.
|
||||
/// - targets: project targets specs.
|
||||
/// - nativeTargets: generated native targes in the Xcode project.
|
||||
/// - objects: Xcode project objects.
|
||||
/// - graph: dependencies graph.
|
||||
/// - Throws: an error if it fails generating the target dependencies
|
||||
func generateTargetDependencies(path: AbsolutePath,
|
||||
targets: [Target],
|
||||
nativeTargets: [String: PBXNativeTarget],
|
||||
|
|
|
@ -92,15 +92,14 @@ class Graph: Graphing {
|
|||
targetNode.dependencies.forEach({ dependencies.insert($0) })
|
||||
targetNode.dependencies.compactMap({ $0 as? TargetNode }).forEach(add)
|
||||
}
|
||||
if let target = cache.targetNodes[path]?[name] {
|
||||
add(target)
|
||||
if let targetNode = self.targetNode(path: path, name: name) {
|
||||
add(targetNode)
|
||||
}
|
||||
return dependencies
|
||||
}
|
||||
|
||||
func targetDependencies(path: AbsolutePath, name: String) -> [String] {
|
||||
guard let targetNodes = cache.targetNodes[path] else { return [] }
|
||||
guard let targetNode = targetNodes[name] else { return [] }
|
||||
guard let targetNode = self.targetNode(path: path, name: name) else { return [] }
|
||||
return targetNode.dependencies
|
||||
.compactMap({ $0 as? TargetNode })
|
||||
.filter({ $0.path == path })
|
||||
|
@ -108,8 +107,7 @@ class Graph: Graphing {
|
|||
}
|
||||
|
||||
func linkableDependencies(path: AbsolutePath, name: String) throws -> [DependencyReference] {
|
||||
guard let targetNodes = cache.targetNodes[path] else { return [] }
|
||||
guard let targetNode = targetNodes[name] else { return [] }
|
||||
guard let targetNode = self.targetNode(path: path, name: name) else { return [] }
|
||||
|
||||
var references: [DependencyReference] = []
|
||||
|
||||
|
@ -136,8 +134,7 @@ class Graph: Graphing {
|
|||
}
|
||||
|
||||
func librariesPublicHeadersFolders(path: AbsolutePath, name: String) -> [AbsolutePath] {
|
||||
guard let targetNodes = cache.targetNodes[path] else { return [] }
|
||||
guard let targetNode = targetNodes[name] else { return [] }
|
||||
guard let targetNode = self.targetNode(path: path, name: name) else { return [] }
|
||||
return targetNode
|
||||
.dependencies
|
||||
.compactMap({ $0 as? LibraryNode })
|
||||
|
@ -147,8 +144,7 @@ class Graph: Graphing {
|
|||
func embeddableFrameworks(path: AbsolutePath,
|
||||
name: String,
|
||||
shell: Shelling) throws -> [DependencyReference] {
|
||||
guard let targetNodes = cache.targetNodes[path] else { return [] }
|
||||
guard let targetNode = targetNodes[name] else { return [] }
|
||||
guard let targetNode = self.targetNode(path: path, name: name) else { return [] }
|
||||
|
||||
let validProducts: [Product] = [
|
||||
.app,
|
||||
|
@ -188,4 +184,16 @@ class Graph: Graphing {
|
|||
}))
|
||||
return references
|
||||
}
|
||||
|
||||
// MARK: - Fileprivate
|
||||
|
||||
fileprivate func targetNode(path: AbsolutePath, name: String) -> TargetNode? {
|
||||
if let targetNode = self.entryNodes.compactMap({ $0 as? TargetNode }).first(where: {
|
||||
$0.path == path && $0.target.name == name
|
||||
}) {
|
||||
return targetNode
|
||||
}
|
||||
guard let targetNodes = cache.targetNodes[path] else { return nil }
|
||||
return targetNodes[name]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ class GraphLoader: GraphLoading {
|
|||
fileprivate func loadProject(path: AbsolutePath) throws -> Graph {
|
||||
let cache = GraphLoaderCache()
|
||||
let graphCircularDetector = GraphCircularDetector()
|
||||
let project = try Project.at(path, cache: cache)
|
||||
let project = try Project.at(path, cache: cache, graphCircularDetector: graphCircularDetector)
|
||||
let entryNodes: [GraphNode] = try project.targets.map({ $0.name }).map { targetName in
|
||||
return try TargetNode.read(name: targetName, path: path, cache: cache, graphCircularDetector: graphCircularDetector)
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ class GraphLoader: GraphLoading {
|
|||
let graphCircularDetector = GraphCircularDetector()
|
||||
let workspace = try Workspace.at(path)
|
||||
let projects = try workspace.projects.map { (projectPath) -> (AbsolutePath, Project) in
|
||||
return try (projectPath, Project.at(projectPath, cache: cache))
|
||||
return try (projectPath, Project.at(projectPath, cache: cache, graphCircularDetector: graphCircularDetector))
|
||||
}
|
||||
let entryNodes = try projects.flatMap { (project) -> [TargetNode] in
|
||||
return try project.1.targets.map({ $0.name }).map { targetName in
|
||||
|
|
|
@ -53,7 +53,7 @@ class TargetNode: GraphNode {
|
|||
cache: GraphLoaderCaching,
|
||||
graphCircularDetector: GraphCircularDetecting) throws -> TargetNode {
|
||||
if let targetNode = cache.targetNode(path, name: name) { return targetNode }
|
||||
let project = try Project.at(path, cache: cache)
|
||||
let project = try Project.at(path, cache: cache, graphCircularDetector: graphCircularDetector)
|
||||
|
||||
guard let target = project.targets.first(where: { $0.name == name }) else {
|
||||
throw GraphLoadingError.targetNotFound(name, path)
|
||||
|
|
|
@ -25,17 +25,24 @@ class Project: Equatable {
|
|||
|
||||
// MARK: - Init
|
||||
|
||||
static func at(_ path: AbsolutePath, cache: GraphLoaderCaching) throws -> Project {
|
||||
static func at(_ path: AbsolutePath, cache: GraphLoaderCaching, graphCircularDetector: GraphCircularDetecting) throws -> Project {
|
||||
if let project = cache.project(path) {
|
||||
return project
|
||||
} else {
|
||||
let project = try Project(path: path)
|
||||
let project = try Project(path: path, cache: cache)
|
||||
cache.add(project: project)
|
||||
|
||||
for target in project.targets {
|
||||
if cache.targetNode(path, name: target.name) != nil { continue }
|
||||
_ = try TargetNode.read(name: target.name, path: path, cache: cache, graphCircularDetector: graphCircularDetector)
|
||||
}
|
||||
|
||||
return project
|
||||
}
|
||||
}
|
||||
|
||||
init(path: AbsolutePath,
|
||||
cache _: GraphLoaderCaching,
|
||||
fileHandler: FileHandling = FileHandler(),
|
||||
manifestLoader: GraphManifestLoading = GraphManifestLoader()) throws {
|
||||
let projectPath = path.appending(component: Constants.Manifest.project)
|
||||
|
|
|
@ -5,7 +5,7 @@ import XCTest
|
|||
final class WorkspaceTests: XCTestCase {
|
||||
func test_toJSON() {
|
||||
let subject = Workspace(name: "name", projects: ["/path/to/project"])
|
||||
let expected = "{\"name\": \"name\", \"project\": [\"/path/to/project\"]}"
|
||||
let expected = "{\"name\": \"name\", \"projects\": [\"/path/to/project\"]}"
|
||||
assertCodableEqualToJson(subject, expected)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue