Update generators to use ProjectGroups
This commit is contained in:
parent
4b42783759
commit
58c5ba1e92
|
@ -18,6 +18,7 @@
|
|||
3D92B78020A823FF006711E5 /* NSError+TestData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B77F20A823FF006711E5 /* NSError+TestData.swift */; };
|
||||
3D92B78E20A8298F006711E5 /* ConfigGeneratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B78D20A8298F006711E5 /* ConfigGeneratorTests.swift */; };
|
||||
3D92B79120A82A82006711E5 /* Graph+TestData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B79020A82A82006711E5 /* Graph+TestData.swift */; };
|
||||
3D92B79320A83BC3006711E5 /* ProjectGroups.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D92B79220A83BC3006711E5 /* ProjectGroups.swift */; };
|
||||
66F6DC2FC19AB1F6D332D8E8 /* ArgumentParserResult+TestData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66F6D37333CBFF51EA0098DD /* ArgumentParserResult+TestData.swift */; };
|
||||
B9013DD5206FEEDF007B1A34 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9013DD4206FEEDF007B1A34 /* Sparkle.framework */; };
|
||||
B9013DD6206FEEEA007B1A34 /* Sparkle.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B9013DD4206FEEDF007B1A34 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
|
@ -237,6 +238,7 @@
|
|||
3D92B77F20A823FF006711E5 /* NSError+TestData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSError+TestData.swift"; sourceTree = "<group>"; };
|
||||
3D92B78D20A8298F006711E5 /* ConfigGeneratorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigGeneratorTests.swift; sourceTree = "<group>"; };
|
||||
3D92B79020A82A82006711E5 /* Graph+TestData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Graph+TestData.swift"; sourceTree = "<group>"; };
|
||||
3D92B79220A83BC3006711E5 /* ProjectGroups.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProjectGroups.swift; sourceTree = "<group>"; };
|
||||
66F6D37333CBFF51EA0098DD /* ArgumentParserResult+TestData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ArgumentParserResult+TestData.swift"; sourceTree = "<group>"; };
|
||||
B9013DD4206FEEDF007B1A34 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Sparkle.framework; sourceTree = "<group>"; };
|
||||
B9157D5220A24B4300C2EEBA /* VersionCommandTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionCommandTests.swift; sourceTree = "<group>"; };
|
||||
|
@ -651,6 +653,7 @@
|
|||
B95895FA208A2FFB00F00ACF /* WorkspaceGenerator.swift */,
|
||||
3D4C0B8720A6507B003D09B0 /* ConfigGenerator.swift */,
|
||||
3D4C0B9B20A6C470003D09B0 /* FileGenerator.swift */,
|
||||
3D92B79220A83BC3006711E5 /* ProjectGroups.swift */,
|
||||
);
|
||||
path = Generator;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1053,6 +1056,7 @@
|
|||
B95895F3208A2ACF00F00ACF /* ProjectGenerator.swift in Sources */,
|
||||
B9FB2DE52086544900BC2FB3 /* Workspace.swift in Sources */,
|
||||
B9B629C120864E7D00EE9E07 /* DumpCommand.swift in Sources */,
|
||||
3D92B79320A83BC3006711E5 /* ProjectGroups.swift in Sources */,
|
||||
3D4C0BA220A6ED37003D09B0 /* CommandCheck.swift in Sources */,
|
||||
B9FB2DE42086544900BC2FB3 /* Config.swift in Sources */,
|
||||
B9FB2DDF208653E000BC2FB3 /* GraphNode.swift in Sources */,
|
||||
|
|
|
@ -9,18 +9,41 @@ protocol ConfigGenerating: AnyObject {
|
|||
/// - Parameters:
|
||||
/// - project: project spec.
|
||||
/// - pbxproj: Xcode project PBXProj object.
|
||||
/// - mainGroup: Xcode project main group.
|
||||
/// - groups: Project groups.
|
||||
/// - sourceRootPath: path to the folder that contains the generated project.
|
||||
/// - context: generation context.
|
||||
/// - Returns: the confniguration list reference.
|
||||
/// - Returns: the configuration list reference.
|
||||
/// - Throws: an error if the generation fails.
|
||||
func generateProjectConfig(project: Project,
|
||||
pbxproj: PBXProj,
|
||||
mainGroup: PBXGroup,
|
||||
groups: ProjectGroups,
|
||||
sourceRootPath: AbsolutePath,
|
||||
context: GeneratorContexting) throws -> PBXObjectReference
|
||||
|
||||
/// Generates the manifests target configuration.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - pbxproj: Xcode project PBXProj object.
|
||||
/// - context: generation context.
|
||||
/// - Returns: the configuration list reference.
|
||||
/// - Throws: an error if the generation fails.
|
||||
func generateManifestsConfig(pbxproj: PBXProj, context: GeneratorContexting) throws -> PBXObjectReference
|
||||
|
||||
/// Generates the target configuration list and configurations.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - target: target spec.
|
||||
/// - pbxproj: Xcode project PBXProj object.
|
||||
/// - groups: Project groups.
|
||||
/// - sourceRootPath: path to the folder that contains the generated project.
|
||||
/// - context: generation context.
|
||||
/// - Returns: the configuration list reference.
|
||||
/// - Throws: an error if the generation fails.
|
||||
func generateTargetConfig(target: Target,
|
||||
pbxproj: PBXProj,
|
||||
groups: ProjectGroups,
|
||||
sourceRootPath: AbsolutePath,
|
||||
context: GeneratorContexting) throws -> PBXObjectReference
|
||||
}
|
||||
|
||||
/// Config generator.
|
||||
|
@ -40,21 +63,16 @@ final class ConfigGenerator: ConfigGenerating {
|
|||
/// - Parameters:
|
||||
/// - project: project spec.
|
||||
/// - pbxproj: Xcode project PBXProj object.
|
||||
/// - mainGroup: Xcode project main group.
|
||||
/// - groups: Project groups.
|
||||
/// - sourceRootPath: path to the folder that contains the generated project.
|
||||
/// - context: generation context.
|
||||
/// - Returns: the confniguration list reference.
|
||||
/// - Throws: an error if the generation fails.
|
||||
func generateProjectConfig(project: Project,
|
||||
pbxproj: PBXProj,
|
||||
mainGroup: PBXGroup,
|
||||
groups: ProjectGroups,
|
||||
sourceRootPath: AbsolutePath,
|
||||
context: GeneratorContexting) throws -> PBXObjectReference {
|
||||
/// Configurations group
|
||||
let configsGroup = PBXGroup(children: [], sourceTree: .group, name: "Configurations")
|
||||
let configsGroupReference = pbxproj.objects.addObject(configsGroup)
|
||||
mainGroup.children.append(configsGroupReference)
|
||||
|
||||
/// Default build settings
|
||||
let defaultAll = BuildSettingsProvider.projectDefault(variant: .all)
|
||||
let defaultDebug = BuildSettingsProvider.projectDefault(variant: .debug)
|
||||
|
@ -70,7 +88,7 @@ final class ConfigGenerator: ConfigGenerating {
|
|||
extend(buildSettings: &debugSettings, with: debugConfig.settings)
|
||||
if let xcconfigDebug = debugConfig.xcconfig {
|
||||
let fileReference = try fileGenerator.generateFile(path: xcconfigDebug,
|
||||
in: configsGroup,
|
||||
in: groups.projectConfigurations(),
|
||||
sourceRootPath: sourceRootPath,
|
||||
context: context)
|
||||
debugConfiguration.baseConfigurationReference = fileReference.reference
|
||||
|
@ -89,7 +107,7 @@ final class ConfigGenerator: ConfigGenerating {
|
|||
extend(buildSettings: &releaseSettings, with: releaseConfig.settings)
|
||||
if let xcconfigRelease = releaseConfig.xcconfig {
|
||||
let fileReference = try fileGenerator.generateFile(path: xcconfigRelease,
|
||||
in: configsGroup,
|
||||
in: groups.projectConfigurations(),
|
||||
sourceRootPath: sourceRootPath,
|
||||
context: context)
|
||||
releaseConfiguration.baseConfigurationReference = fileReference.reference
|
||||
|
@ -135,6 +153,29 @@ final class ConfigGenerator: ConfigGenerating {
|
|||
return configurationListReference
|
||||
}
|
||||
|
||||
/// Generates the target configuration list and configurations.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - target: target spec.
|
||||
/// - pbxproj: Xcode project PBXProj object.
|
||||
/// - groups: Project groups.
|
||||
/// - sourceRootPath: path to the folder that contains the generated project.
|
||||
/// - context: generation context.
|
||||
/// - Returns: the configuration list reference.
|
||||
/// - Throws: an error if the generation fails.
|
||||
func generateTargetConfig(target _: Target,
|
||||
pbxproj: PBXProj,
|
||||
groups _: ProjectGroups,
|
||||
sourceRootPath _: AbsolutePath,
|
||||
context _: GeneratorContexting) throws -> PBXObjectReference {
|
||||
let configurationList = XCConfigurationList(buildConfigurations: [])
|
||||
let configurationListReference = pbxproj.objects.addObject(configurationList)
|
||||
// TODO:
|
||||
return configurationListReference
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
/// Extends build settings with other build settings.
|
||||
///
|
||||
/// - Parameters:
|
||||
|
|
|
@ -53,34 +53,22 @@ final class ProjectGenerator: ProjectGenerating {
|
|||
let pbxproj = PBXProj(objectVersion: Xcode.Default.objectVersion,
|
||||
archiveVersion: Xcode.LastKnown.archiveVersion,
|
||||
classes: [:])
|
||||
|
||||
/// Main group
|
||||
let mainGroup = PBXGroup(children: [],
|
||||
sourceTree: .group,
|
||||
path: project.path.relative(to: sourceRootPath).asString)
|
||||
let mainGroupReference = pbxproj.objects.addObject(mainGroup)
|
||||
|
||||
// Configuration
|
||||
let groups = ProjectGroups.generate(project: project, pbxproj: pbxproj, sourceRootPath: sourceRootPath)
|
||||
let configurationListReference = try configGenerator.generateProjectConfig(project: project,
|
||||
pbxproj: pbxproj,
|
||||
mainGroup: mainGroup,
|
||||
groups: groups,
|
||||
sourceRootPath: sourceRootPath,
|
||||
context: context)
|
||||
|
||||
/// Products group
|
||||
let productsGroup = PBXGroup(children: [], sourceTree: .buildProductsDir, name: "Products")
|
||||
let productsGroupReference = pbxproj.objects.addObject(productsGroup)
|
||||
mainGroup.children.append(productsGroupReference)
|
||||
|
||||
/// Generate project object.
|
||||
let pbxProject = PBXProject(name: project.name,
|
||||
buildConfigurationList: configurationListReference,
|
||||
compatibilityVersion: Xcode.Default.compatibilityVersion,
|
||||
mainGroup: mainGroupReference,
|
||||
mainGroup: groups.main.reference,
|
||||
developmentRegion: Xcode.Default.developmentRegion,
|
||||
hasScannedForEncodings: 0,
|
||||
knownRegions: ["en"],
|
||||
productRefGroup: productsGroupReference,
|
||||
productRefGroup: groups.products.reference,
|
||||
projectDirPath: "",
|
||||
projectReferences: [],
|
||||
projectRoots: [],
|
||||
|
@ -89,14 +77,20 @@ final class ProjectGenerator: ProjectGenerating {
|
|||
let projectReference = pbxproj.objects.addObject(pbxProject)
|
||||
pbxproj.rootObject = projectReference
|
||||
|
||||
/// Targets
|
||||
try targetGenerator.generateManifestsTarget(project: project,
|
||||
pbxproj: pbxproj,
|
||||
pbxProject: pbxProject,
|
||||
mainGroup: mainGroup,
|
||||
productsGroup: productsGroup,
|
||||
groups: groups,
|
||||
sourceRootPath: sourceRootPath,
|
||||
context: context)
|
||||
try project.targets.forEach { target in
|
||||
try targetGenerator.generateTarget(target: target,
|
||||
pbxproj: pbxproj,
|
||||
pbxProject: pbxProject,
|
||||
groups: groups,
|
||||
sourceRootPath: sourceRootPath,
|
||||
context: context)
|
||||
}
|
||||
|
||||
/// Write.
|
||||
let xcodeproj = XcodeProj(workspace: workspace, pbxproj: pbxproj)
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
import Basic
|
||||
import Foundation
|
||||
import xcodeproj
|
||||
|
||||
/// Object that contains references to the project base groups.
|
||||
class ProjectGroups {
|
||||
/// Project main group.
|
||||
let main: PBXGroup
|
||||
|
||||
/// Project products group.
|
||||
let products: PBXGroup
|
||||
|
||||
/// Project support group.
|
||||
let support: PBXGroup
|
||||
|
||||
/// Project project description group.
|
||||
let projectDescription: PBXGroup
|
||||
|
||||
/// Targets group.
|
||||
fileprivate let targets: PBXGroup
|
||||
|
||||
/// Frameworks group.
|
||||
fileprivate let frameworks: PBXGroup
|
||||
|
||||
/// PBXProj instance.
|
||||
fileprivate let pbxproj: PBXProj
|
||||
|
||||
/// Project configurations group.
|
||||
fileprivate let configurations: PBXGroup
|
||||
|
||||
/// Initializes the object with the group.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - main: main group.
|
||||
/// - products: products group.
|
||||
/// - configurations: configurations group.
|
||||
/// - support: support group.
|
||||
/// - targets: targets group.
|
||||
/// - projectDescription: project description group.
|
||||
init(main: PBXGroup,
|
||||
products: PBXGroup,
|
||||
configurations: PBXGroup,
|
||||
support: PBXGroup,
|
||||
targets: PBXGroup,
|
||||
projectDescription: PBXGroup,
|
||||
frameworks: PBXGroup,
|
||||
pbxproj: PBXProj) {
|
||||
self.main = main
|
||||
self.products = products
|
||||
self.support = support
|
||||
self.targets = targets
|
||||
self.configurations = configurations
|
||||
self.projectDescription = projectDescription
|
||||
self.frameworks = frameworks
|
||||
self.pbxproj = pbxproj
|
||||
}
|
||||
|
||||
/// Returns a group that should contain all the target build files (sources & resources)
|
||||
///
|
||||
/// - Parameter name: target name.
|
||||
/// - Returns: group to be used.
|
||||
/// - Throws: an error if the creation fails.
|
||||
func target(name: String) throws -> PBXGroup {
|
||||
if let group = targets.group(named: name) {
|
||||
return group
|
||||
} else {
|
||||
return try targets.addGroup(named: name, options: .withoutFolder).first!
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a group that should contain all the frameworks of a given target.
|
||||
///
|
||||
/// - Parameter target: target name.
|
||||
/// - Returns: group to be used.
|
||||
/// - Throws: an error if the creation fails.
|
||||
func targetFrameworks(target: String) throws -> PBXGroup {
|
||||
if let group = frameworks.group(named: target) {
|
||||
return group
|
||||
} else {
|
||||
return try frameworks.addGroup(named: target, options: .withoutFolder).first!
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a group that should contain all the configurations of a given target.
|
||||
///
|
||||
/// - Parameter target: target name.
|
||||
/// - Returns: group to be used.
|
||||
/// - Throws: an error if the creation fails.
|
||||
func targetConfigurations(_ target: String) throws -> PBXGroup {
|
||||
if let group = configurations.group(named: target) {
|
||||
return group
|
||||
} else {
|
||||
return try configurations.addGroup(named: target, options: .withoutFolder).first!
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a group that should contain all the configurations of a project.
|
||||
///
|
||||
/// - Returns: the group to be used.
|
||||
/// - Throws: an error if the creation fails.
|
||||
func projectConfigurations() throws -> PBXGroup {
|
||||
if let group = configurations.group(named: "Project") {
|
||||
return group
|
||||
} else {
|
||||
return try configurations.addGroup(named: "Project", options: .withoutFolder).first!
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates all the Xcode project base groups and returns an instance of ProjectGroups
|
||||
/// that contains a reference to them.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - project: project spec.
|
||||
/// - pbxproj: PBXProj instance.
|
||||
/// - sourceRootPath: path to the folder where the Xcode project is getting created.
|
||||
/// - Returns: project groups instance.
|
||||
static func generate(project: Project,
|
||||
pbxproj: PBXProj,
|
||||
sourceRootPath: AbsolutePath) -> ProjectGroups {
|
||||
/// Main
|
||||
let mainGroup = PBXGroup(children: [],
|
||||
sourceTree: .group,
|
||||
path: project.path.relative(to: sourceRootPath).asString)
|
||||
pbxproj.objects.addObject(mainGroup)
|
||||
|
||||
/// Targets
|
||||
let targetsGroup = PBXGroup(children: [], sourceTree: .group, name: "Targets")
|
||||
let targetsGroupReference = pbxproj.objects.addObject(targetsGroup)
|
||||
mainGroup.children.append(targetsGroupReference)
|
||||
|
||||
/// Configurations
|
||||
let configurationsGroup = PBXGroup(children: [], sourceTree: .group, name: "Configurations")
|
||||
let configurationsGroupReference = pbxproj.objects.addObject(configurationsGroup)
|
||||
mainGroup.children.append(configurationsGroupReference)
|
||||
|
||||
/// Support
|
||||
let supportGroup = PBXGroup(children: [], sourceTree: .group, name: "Support")
|
||||
let supportGroupReference = pbxproj.objects.addObject(supportGroup)
|
||||
mainGroup.children.append(supportGroupReference)
|
||||
|
||||
/// Configurations
|
||||
let projectDescriptionGroup = PBXGroup(children: [], sourceTree: .group, name: "ProjectDescription")
|
||||
let projectDescriptionGroupReference = pbxproj.objects.addObject(projectDescriptionGroup)
|
||||
mainGroup.children.append(projectDescriptionGroupReference)
|
||||
|
||||
/// Frameworks
|
||||
let frameworksGroup = PBXGroup(children: [], sourceTree: .group, name: "Frameworks")
|
||||
let frameworksGroupReference = pbxproj.objects.addObject(frameworksGroup)
|
||||
mainGroup.children.append(frameworksGroupReference)
|
||||
|
||||
/// Products
|
||||
let productsGroup = PBXGroup(children: [], sourceTree: .buildProductsDir, name: "Products")
|
||||
let productsGroupReference = pbxproj.objects.addObject(productsGroup)
|
||||
mainGroup.children.append(productsGroupReference)
|
||||
|
||||
return ProjectGroups(main: mainGroup,
|
||||
products: productsGroup,
|
||||
configurations: configurationsGroup,
|
||||
support: supportGroup,
|
||||
targets: targetsGroup,
|
||||
projectDescription: projectDescriptionGroup,
|
||||
frameworks: frameworksGroup,
|
||||
pbxproj: pbxproj)
|
||||
}
|
||||
}
|
|
@ -2,16 +2,44 @@ import Basic
|
|||
import Foundation
|
||||
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.
|
||||
/// - Throws: an error if the generation fails.
|
||||
func generateManifestsTarget(project: Project,
|
||||
pbxproj: PBXProj,
|
||||
pbxProject: PBXProject,
|
||||
mainGroup: PBXGroup,
|
||||
productsGroup: PBXGroup,
|
||||
groups: ProjectGroups,
|
||||
sourceRootPath: AbsolutePath,
|
||||
context: GeneratorContexting) throws
|
||||
|
||||
/// Generates a native target.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - target: Target 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.
|
||||
/// - Throws: an error if the generation fails.
|
||||
func generateTarget(target: Target,
|
||||
pbxproj: PBXProj,
|
||||
pbxProject: PBXProject,
|
||||
groups: ProjectGroups,
|
||||
sourceRootPath: AbsolutePath,
|
||||
context: GeneratorContexting) throws
|
||||
}
|
||||
|
||||
/// Target generator.
|
||||
final class TargetGenerator: TargetGenerating {
|
||||
/// Config generator.
|
||||
let configGenerator: ConfigGenerating
|
||||
|
@ -19,17 +47,31 @@ final class TargetGenerator: TargetGenerating {
|
|||
/// File generator.
|
||||
let fileGenerator: FileGenerating
|
||||
|
||||
/// Initializes the target generator with its attributes.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - configGenerator: config generator.
|
||||
/// - fileGenerator: file generator.
|
||||
init(configGenerator: ConfigGenerating = ConfigGenerator(),
|
||||
fileGenerator: FileGenerating = FileGenerator()) {
|
||||
self.configGenerator = configGenerator
|
||||
self.fileGenerator = fileGenerator
|
||||
}
|
||||
|
||||
/// 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.
|
||||
/// - Throws: an error if the generation fails.
|
||||
func generateManifestsTarget(project: Project,
|
||||
pbxproj: PBXProj,
|
||||
pbxProject: PBXProject,
|
||||
mainGroup: PBXGroup,
|
||||
productsGroup: PBXGroup,
|
||||
groups: ProjectGroups,
|
||||
sourceRootPath: AbsolutePath,
|
||||
context: GeneratorContexting) throws {
|
||||
/// Names
|
||||
|
@ -39,21 +81,22 @@ final class TargetGenerator: TargetGenerating {
|
|||
/// Products reference.
|
||||
let productFileReference = PBXFileReference(sourceTree: .buildProductsDir, name: frameworkName)
|
||||
let productFileReferenceRef = pbxproj.objects.addObject(productFileReference)
|
||||
productsGroup.children.append(productFileReferenceRef)
|
||||
|
||||
/// Group
|
||||
let group = PBXGroup(sourceTree: .group, name: name)
|
||||
let groupReference = pbxproj.objects.addObject(group)
|
||||
mainGroup.children.insert(groupReference, at: 0)
|
||||
groups.products.children.append(productFileReferenceRef)
|
||||
|
||||
/// Files
|
||||
var files: [PBXObjectReference] = []
|
||||
let projectManifestPath = project.path.appending(component: Constants.Manifest.project)
|
||||
let projectManifest = try fileGenerator.generateFile(path: projectManifestPath, in: group, sourceRootPath: sourceRootPath, context: context)
|
||||
let projectManifest = try fileGenerator.generateFile(path: projectManifestPath,
|
||||
in: groups.projectDescription,
|
||||
sourceRootPath: sourceRootPath,
|
||||
context: context)
|
||||
files.append(projectManifest.reference)
|
||||
if let config = project.config {
|
||||
let configManifestPath = config.path.appending(component: Constants.Manifest.config)
|
||||
let configManifest = try fileGenerator.generateFile(path: configManifestPath, in: group, sourceRootPath: sourceRootPath, context: context)
|
||||
let configManifest = try fileGenerator.generateFile(path: configManifestPath,
|
||||
in: groups.projectDescription,
|
||||
sourceRootPath: sourceRootPath,
|
||||
context: context)
|
||||
files.append(configManifest.reference)
|
||||
}
|
||||
|
||||
|
@ -75,4 +118,45 @@ final class TargetGenerator: TargetGenerating {
|
|||
let targetReference = pbxproj.objects.addObject(target)
|
||||
pbxProject.targets.append(targetReference)
|
||||
}
|
||||
|
||||
/// Generates a native target.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - target: Target 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.
|
||||
/// - Throws: an error if the generation fails.
|
||||
func generateTarget(target: Target,
|
||||
pbxproj: PBXProj,
|
||||
pbxProject: PBXProject,
|
||||
groups: ProjectGroups,
|
||||
sourceRootPath _: AbsolutePath,
|
||||
context _: GeneratorContexting) throws {
|
||||
/// Names
|
||||
let name = target.name
|
||||
let productName = "\(target.name).\(target.product.xcodeValue.fileExtension!)"
|
||||
|
||||
/// Products reference.
|
||||
let productFileReference = PBXFileReference(sourceTree: .buildProductsDir, name: productName)
|
||||
let productFileReferenceRef = pbxproj.objects.addObject(productFileReference)
|
||||
groups.products.children.append(productFileReferenceRef)
|
||||
|
||||
/// Group
|
||||
let group = try groups.target(name: target.name)
|
||||
|
||||
/// Target
|
||||
let target = PBXNativeTarget(name: target.name,
|
||||
buildConfigurationList: nil,
|
||||
buildPhases: [],
|
||||
buildRules: [],
|
||||
dependencies: [],
|
||||
productName: productName,
|
||||
productReference: productFileReferenceRef,
|
||||
productType: target.product.xcodeValue)
|
||||
let targetReference = pbxproj.objects.addObject(target)
|
||||
pbxProject.targets.append(targetReference)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Foundation
|
||||
import xcodeproj
|
||||
|
||||
/// Product type.
|
||||
///
|
||||
|
@ -37,38 +38,38 @@ public enum Product: String {
|
|||
|
||||
extension Product {
|
||||
/// Returns the Xcode value.
|
||||
var xcodeValue: String {
|
||||
var xcodeValue: PBXProductType {
|
||||
switch self {
|
||||
case .app:
|
||||
return "com.apple.product-type.application"
|
||||
return .application
|
||||
case .staticLibrary:
|
||||
return "com.apple.product-type.library.static"
|
||||
return .staticLibrary
|
||||
case .dynamicLibrary:
|
||||
return "com.apple.product-type.library.dynamic"
|
||||
return .dynamicLibrary
|
||||
case .framework:
|
||||
return "com.apple.product-type.framework"
|
||||
return .framework
|
||||
case .unitTests:
|
||||
return "com.apple.product-type.bundle.unit-test"
|
||||
return .unitTestBundle
|
||||
case .uiTests:
|
||||
return "com.apple.product-type.bundle.ui-testing"
|
||||
return .uiTestBundle
|
||||
case .appExtension:
|
||||
return "com.apple.product-type.app-extension"
|
||||
return .appExtension
|
||||
case .watchApp:
|
||||
return "com.apple.product-type.application.watchapp"
|
||||
return .watchApp
|
||||
case .watch2App:
|
||||
return "com.apple.product-type.application.watchapp2"
|
||||
return .watch2App
|
||||
case .watchExtension:
|
||||
return "com.apple.product-type.watchkit-extension"
|
||||
return .watch2App
|
||||
case .watch2Extension:
|
||||
return "com.apple.product-type.watchkit2-extension"
|
||||
return .watch2Extension
|
||||
case .tvExtension:
|
||||
return "com.apple.product-type.tv-app-extension"
|
||||
return .watch2Extension
|
||||
case .messagesApplication:
|
||||
return "com.apple.product-type.application.messages"
|
||||
return .messagesApplication
|
||||
case .messagesExtension:
|
||||
return "com.apple.product-type.app-extension.messages"
|
||||
return .messagesExtension
|
||||
case .stickerPack:
|
||||
return "com.apple.product-type.app-extension.messages-sticker-pack"
|
||||
return .stickerPack
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,12 +19,10 @@ final class ConfigGeneratorTests: XCTestCase {
|
|||
}
|
||||
|
||||
func testGenerateProjectConfig() throws {
|
||||
let mainGroup = try generateProjectConfig()
|
||||
let groups = try generateProjectConfig()
|
||||
|
||||
XCTAssertEqual(mainGroup.children.count, 1)
|
||||
|
||||
let configurationsGroup: PBXGroup = try mainGroup.children.first!.object()
|
||||
XCTAssertEqual(configurationsGroup.name, "Configurations")
|
||||
let configurationsGroup: PBXGroup = try groups.projectConfigurations()
|
||||
XCTAssertEqual(configurationsGroup.name, "Project")
|
||||
XCTAssertEqual(configurationsGroup.sourceTree, .group)
|
||||
XCTAssertNil(configurationsGroup.path)
|
||||
|
||||
|
@ -56,10 +54,8 @@ final class ConfigGeneratorTests: XCTestCase {
|
|||
XCTAssertEqual(releaseConfig.buildSettings["Base"] as? String, "Base")
|
||||
}
|
||||
|
||||
private func generateProjectConfig() throws -> PBXGroup {
|
||||
private func generateProjectConfig() throws -> ProjectGroups {
|
||||
let dir = try TemporaryDirectory()
|
||||
let mainGroup = PBXGroup(sourceTree: .absolute, name: "main", path: dir.path.asString)
|
||||
_ = pbxproj.objects.addObject(mainGroup)
|
||||
let xcconfigsDir = dir.path.appending(component: "xcconfigs")
|
||||
try xcconfigsDir.mkpath()
|
||||
try xcconfigsDir.appending(component: "debug.xcconfig").write("")
|
||||
|
@ -74,11 +70,12 @@ final class ConfigGeneratorTests: XCTestCase {
|
|||
release: Configuration(settings: ["Release": "Release"],
|
||||
xcconfig: xcconfigsDir.appending(component: "release.xcconfig"))),
|
||||
targets: [])
|
||||
let groups = ProjectGroups.generate(project: project, pbxproj: pbxproj, sourceRootPath: dir.path)
|
||||
_ = try subject.generateProjectConfig(project: project,
|
||||
pbxproj: pbxproj,
|
||||
mainGroup: mainGroup,
|
||||
groups: groups,
|
||||
sourceRootPath: dir.path,
|
||||
context: context)
|
||||
return mainGroup
|
||||
return groups
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
import Foundation
|
||||
@testable import xcbuddykit
|
||||
@testable import xcodeproj
|
||||
import XCTest
|
||||
|
||||
final class ProductTests: XCTestCase {
|
||||
func test_xcodeValue() {
|
||||
XCTAssertEqual(Product.app.xcodeValue, "com.apple.product-type.application")
|
||||
XCTAssertEqual(Product.staticLibrary.xcodeValue, "com.apple.product-type.library.static")
|
||||
XCTAssertEqual(Product.dynamicLibrary.xcodeValue, "com.apple.product-type.library.dynamic")
|
||||
XCTAssertEqual(Product.framework.xcodeValue, "com.apple.product-type.framework")
|
||||
XCTAssertEqual(Product.unitTests.xcodeValue, "com.apple.product-type.bundle.unit-test")
|
||||
XCTAssertEqual(Product.uiTests.xcodeValue, "com.apple.product-type.bundle.ui-testing")
|
||||
XCTAssertEqual(Product.appExtension.xcodeValue, "com.apple.product-type.app-extension")
|
||||
XCTAssertEqual(Product.watchApp.xcodeValue, "com.apple.product-type.application.watchapp")
|
||||
XCTAssertEqual(Product.watch2App.xcodeValue, "com.apple.product-type.application.watchapp2")
|
||||
XCTAssertEqual(Product.watchExtension.xcodeValue, "com.apple.product-type.watchkit-extension")
|
||||
XCTAssertEqual(Product.watch2Extension.xcodeValue, "com.apple.product-type.watchkit2-extension")
|
||||
XCTAssertEqual(Product.tvExtension.xcodeValue, "com.apple.product-type.tv-app-extension")
|
||||
XCTAssertEqual(Product.messagesApplication.xcodeValue, "com.apple.product-type.application.messages")
|
||||
XCTAssertEqual(Product.messagesExtension.xcodeValue, "com.apple.product-type.app-extension.messages")
|
||||
XCTAssertEqual(Product.stickerPack.xcodeValue, "com.apple.product-type.app-extension.messages-sticker-pack")
|
||||
XCTAssertEqual(Product.app.xcodeValue, PBXProductType.application)
|
||||
XCTAssertEqual(Product.staticLibrary.xcodeValue, PBXProductType.staticLibrary)
|
||||
XCTAssertEqual(Product.dynamicLibrary.xcodeValue, PBXProductType.dynamicLibrary)
|
||||
XCTAssertEqual(Product.framework.xcodeValue, PBXProductType.framework)
|
||||
XCTAssertEqual(Product.unitTests.xcodeValue, PBXProductType.unitTestBundle)
|
||||
XCTAssertEqual(Product.uiTests.xcodeValue, PBXProductType.uiTestBundle)
|
||||
XCTAssertEqual(Product.appExtension.xcodeValue, PBXProductType.appExtension)
|
||||
XCTAssertEqual(Product.watchApp.xcodeValue, PBXProductType.watchApp)
|
||||
XCTAssertEqual(Product.watch2App.xcodeValue, PBXProductType.watch2App)
|
||||
XCTAssertEqual(Product.watchExtension.xcodeValue, PBXProductType.watchExtension)
|
||||
XCTAssertEqual(Product.watch2Extension.xcodeValue, PBXProductType.watch2Extension)
|
||||
XCTAssertEqual(Product.tvExtension.xcodeValue, PBXProductType.tvExtension)
|
||||
XCTAssertEqual(Product.messagesApplication.xcodeValue, PBXProductType.messagesApplication)
|
||||
XCTAssertEqual(Product.messagesExtension.xcodeValue, PBXProductType.messagesExtension)
|
||||
XCTAssertEqual(Product.stickerPack.xcodeValue, PBXProductType.stickerPack)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue