Skip to content

Move external dependencies to Dependencies group in Xcode project #186

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions Sources/Get/get().swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,22 @@ import Utility
- Throws: Error.InvalidDependencyGraph
- Returns: The modules that this manifest requires building
*/
public func get(manifest: Manifest, manifestParser: (path: String, url: String) throws -> Manifest) throws -> [Package] {
public func get(manifest: Manifest, manifestParser: (path: String, url: String) throws -> Manifest) throws -> (rootPackage: Package, externalPackages:[Package]) {
let dir = Path.join(manifest.path.parentDirectory, "Packages")
let box = PackagesDirectory(prefix: dir, manifestParser: manifestParser)

//TODO don't lose the dependency information during the Fetcher process!

let pkgs = try box.recursivelyFetch(manifest.dependencies) + [Package(manifest: manifest, url: manifest.path.parentDirectory)]

let rootPackage = Package(manifest: manifest, url: manifest.path.parentDirectory)
let extPackages = try box.recursivelyFetch(manifest.dependencies)

let pkgs = extPackages + [rootPackage]

for pkg in pkgs {
pkg.dependencies = pkg.manifest.package.dependencies.map{ dep in pkgs.pick{ dep.url == $0.url }! }
}
return pkgs

return (rootPackage, extPackages)
}

//TODO normalize urls eg http://github.com -> https://github.com
Expand Down
24 changes: 8 additions & 16 deletions Sources/Transmute/transmute().swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,19 @@ import PackageType
import Utility
import func libc.exit

public func transmute(packages: [Package], rootdir: String) throws -> ([Module], [Product]) {
public func transmute(rootPackage: Package, externalPackages: [Package]) throws -> (modules: [Module], externalModules: [Module], products: [Product]) {

var products: [Product] = []
var map: [Package: [Module]] = [:]

let packages = externalPackages + [rootPackage]

for package in packages {

let modules: [Module]
do {
modules = try package.modules()
} catch Package.ModuleError.NoModules(let pkg) where pkg.path == rootdir {
} catch Package.ModuleError.NoModules(let pkg) where pkg === rootPackage {
//Ignore and print warning if root package doesn't contain any sources
print("warning: root package '\(pkg)' does not contain any sources")
if packages.count == 1 { exit(0) } //Exit now if there is no more packages
Expand Down Expand Up @@ -66,18 +68,8 @@ public func transmute(packages: [Package], rootdir: String) throws -> ([Module],
// ensure modules depend on the modules of any dependent packages
fillModuleGraph(packages, modulesForPackage: { map[$0]! })

var set = Set<Module>()
var stack = packages.flatMap{ map[$0] ?? [] }
var modules = [Module]()
let modules = recursiveDependencies(packages.flatMap{ map[$0] ?? [] })
let externalModules = recursiveDependencies(externalPackages.flatMap{ map[$0] ?? [] })

while !stack.isEmpty {
let module = stack.removeFirst()
if !set.contains(module) {
set.insert(module)
stack += module.dependencies
modules.append(module)
}
}

return (modules, products)
}
return (modules, externalModules, products)
}
1 change: 1 addition & 0 deletions Sources/Xcodeproj/Module+PBXProj.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ let rootGroupReference = "___RootGroup_"
let productsGroupReference = "____Products_"
let testProductsGroupReference = "TestProducts_"
let sourcesGroupReference = "_____Sources_"
let dependenciesGroupReference = "Dependencies_"
let testsGroupReference = "_______Tests_"
let linkPhaseFileRefPrefix = "_LinkFileRef_"
let sourceGroupFileRefPrefix = "__PBXFileRef_"
Expand Down
4 changes: 2 additions & 2 deletions Sources/Xcodeproj/generate().swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import POSIX
Generates an xcodeproj at the specified path.
- Returns: the path to the generated project
*/
public func generate(dstdir dstdir: String, projectName: String, srcroot: String, modules: [SwiftModule], products: [Product]) throws -> String {
public func generate(dstdir dstdir: String, projectName: String, srcroot: String, modules: [SwiftModule], externalModules: [SwiftModule], products: [Product]) throws -> String {

let xcodeprojName = "\(projectName).xcodeproj"
let xcodeprojPath = try mkdir(dstdir, xcodeprojName)
Expand All @@ -25,7 +25,7 @@ public func generate(dstdir dstdir: String, projectName: String, srcroot: String

////// the pbxproj file describes the project and its targets
try open(xcodeprojPath, "project.pbxproj") { fwrite in
pbxproj(srcroot: srcroot, projectRoot: dstdir, modules: modules, products: products, printer: fwrite)
pbxproj(srcroot: srcroot, projectRoot: dstdir, modules: modules, externalModules: externalModules, products: products, printer: fwrite)
}

////// the scheme acts like an aggregate target for all our targets
Expand Down
22 changes: 16 additions & 6 deletions Sources/Xcodeproj/pbxproj().swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
import PackageType
import Utility

public func pbxproj(srcroot srcroot: String, projectRoot: String, modules: [SwiftModule], products _: [Product], printer print: (String) -> Void) {
let nontests = modules.filter{ !($0 is TestModule) }
let tests = modules.filter{ $0 is TestModule }
public func pbxproj(srcroot srcroot: String, projectRoot: String, modules: [SwiftModule], externalModules: [SwiftModule], products _: [Product], printer print: (String) -> Void) {

let rootModulesSet = Set(modules).subtract(Set(externalModules))
let nonTestRootModules = rootModulesSet.filter{ !($0 is TestModule) }
let (tests, nonTests) = modules.partition{ $0 is TestModule }

print("// !$*UTF8*$!")
print("{")
Expand Down Expand Up @@ -57,7 +59,7 @@ public func pbxproj(srcroot srcroot: String, projectRoot: String, modules: [Swif
////// root group
print(" \(rootGroupReference) = {")
print(" isa = PBXGroup;")
print(" children = (\(packageSwift.0), \(sourcesGroupReference), \(testsGroupReference), \(productsGroupReference));")
print(" children = (\(packageSwift.0), \(sourcesGroupReference), \(dependenciesGroupReference), \(testsGroupReference), \(productsGroupReference));")
print(" sourceTree = '<group>';")
print(" };")

Expand Down Expand Up @@ -157,11 +159,19 @@ public func pbxproj(srcroot srcroot: String, projectRoot: String, modules: [Swif
////// “Sources” group
print(" \(sourcesGroupReference) = {")
print(" isa = PBXGroup;")
print(" children = (" + nontests.map{ $0.groupReference }.joined(separator: ", ") + ");")
print(" children = (" + nonTestRootModules.map{ $0.groupReference }.joined(separator: ", ") + ");")
print(" name = Sources;")
print(" sourceTree = '<group>';")
print(" };")

////// “Dependencies” group
print(" \(dependenciesGroupReference) = {")
print(" isa = PBXGroup;")
print(" children = (" + externalModules.map{ $0.groupReference }.joined(separator: ", ") + ");")
print(" name = Dependencies;")
print(" sourceTree = '<group>';")
print(" };")

////// “Tests” group
print(" \(testsGroupReference) = {")
print(" isa = PBXGroup;")
Expand Down Expand Up @@ -194,7 +204,7 @@ public func pbxproj(srcroot srcroot: String, projectRoot: String, modules: [Swif
}

////// “Products” group
productReferences += nontests.map { $0.productReference }
productReferences += nonTests.map { $0.productReference }

print(" \(productsGroupReference) = {")
print(" isa = PBXGroup;")
Expand Down
16 changes: 9 additions & 7 deletions Sources/swift-build/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,16 @@ do {
return try Manifest(path: path, baseURL: baseURL, swiftc: Toolchain.swiftc, libdir: libdir)
}

func fetch(root: String) throws -> [Package] {
func fetch(root: String) throws -> (rootPackage: Package, externalPackages:[Package]) {
let manifest = try parseManifest(path: root, baseURL: root)
return try get(manifest, manifestParser: parseManifest)
}

switch mode {
case .Build(let conf):
let dirs = try directories()
let packages = try fetch(dirs.root)
let (modules, products) = try transmute(packages, rootdir: dirs.root)
let (rootPackage, externalPackages) = try fetch(dirs.root)
let (modules, externalModules, products) = try transmute(rootPackage, externalPackages: externalPackages)
let yaml = try describe(dirs.build, conf, modules, products, Xcc: opts.Xcc, Xld: opts.Xld, Xswiftc: opts.Xswiftc)
try build(YAMLPath: yaml, target: "default")

Expand All @@ -92,13 +92,15 @@ do {

case .GenerateXcodeproj(let outpath):
let dirs = try directories()
let packages = try fetch(dirs.root)
let (modules, products) = try transmute(packages, rootdir: dirs.root)
let (rootPackage, externalPackages) = try fetch(dirs.root)
let (modules, externalModules, products) = try transmute(rootPackage, externalPackages: externalPackages)

let swiftModules = modules.flatMap{ $0 as? SwiftModule }
let externalSwiftModules = externalModules.flatMap{ $0 as? SwiftModule }

let projectName: String
let dstdir: String
let packageName = packages.last!.name //FIXME coincidental dependency on order
let packageName = rootPackage.name

switch outpath {
case let outpath? where outpath.hasSuffix(".xcodeproj"):
Expand All @@ -114,7 +116,7 @@ do {
projectName = packageName
}

let outpath = try Xcodeproj.generate(dstdir: dstdir, projectName: projectName, srcroot: dirs.root, modules: swiftModules, products: products)
let outpath = try Xcodeproj.generate(dstdir: dstdir, projectName: projectName, srcroot: dirs.root, modules: swiftModules, externalModules: externalSwiftModules, products: products)

print("generated:", outpath.prettied)
}
Expand Down
10 changes: 5 additions & 5 deletions Tests/Transmute/ModuleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,9 @@ extension ModuleTests {
fixture(name: "Miscellaneous/PackageType") { prefix in
let prefix = Path.join(prefix, "App")
let manifest = try Manifest(path: prefix)
let packages = try get(manifest, manifestParser: { try Manifest(path: $0, baseURL: $1) })
let (modules, _) = try transmute(packages, rootdir: prefix)

let (rootPackage, externalPackages) = try get(manifest, manifestParser: { try Manifest(path: $0, baseURL: $1) })
let (modules, _, _) = try transmute(rootPackage, externalPackages: externalPackages)
XCTAssertEqual(modules.count, 3)
XCTAssertEqual(recursiveDependencies(modules).count, 3)
XCTAssertTrue(modules.dropFirst().first is CModule)
Expand All @@ -211,8 +211,8 @@ extension ModuleTests {
fixture(name: "ModuleMaps/Direct") { prefix in
let prefix = Path.join(prefix, "App")
let manifest = try Manifest(path: prefix)
let packages = try get(manifest, manifestParser: { try Manifest(path: $0, baseURL: $1) })
let (modules, _) = try transmute(packages, rootdir: prefix)
let (rootPackage, externalPackages) = try get(manifest, manifestParser: { try Manifest(path: $0, baseURL: $1) })
let (modules, _, _) = try transmute(rootPackage, externalPackages: externalPackages)

XCTAssertEqual(modules.count, 2)
XCTAssertTrue(modules.first is CModule)
Expand Down
2 changes: 1 addition & 1 deletion Tests/Xcodeproj/TestGeneration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class TestGeneration: XCTestCase {
let modules = dummy()
let products: [Product] = []

let outpath = try Xcodeproj.generate(dstdir: dstdir, projectName: projectName, srcroot: srcroot, modules: modules, products: products)
let outpath = try Xcodeproj.generate(dstdir: dstdir, projectName: projectName, srcroot: srcroot, modules: modules, externalModules: [], products: products)

XCTAssertDirectoryExists(outpath)
XCTAssertEqual(outpath, Path.join(dstdir, "\(projectName).xcodeproj"))
Expand Down