From 4a54fe6d2a37c51726ba753ae4d50becc5e6b997 Mon Sep 17 00:00:00 2001 From: Brandon Kase Date: Tue, 31 Oct 2017 22:01:55 -0700 Subject: [PATCH] Support file sources The `sources` key of the project spec only supported directories and not files. Now it supports both! This commit introduces a `getSourceFiles` overload that doesn't explicitly invoke `path.children()`, but instead accepts `children` as a parameter. This allows us to invoke the `children` overload of getSourceFiles with just the files we want to include (determined by specifying the sources). Now for sourcePaths that are files, we group by parents before invoking getSourceFiles in order to reuse the same groups. --- .../TestProject/App_iOS/AppDelegate.swift | 2 + .../Project.xcodeproj/project.pbxproj | 13 +++++++ .../StandaloneFiles/Standalone.swift | 3 ++ Fixtures/TestProject/spec.yml | 4 +- Sources/XcodeGenKit/PBXProjGenerator.swift | 39 +++++++++++++------ 5 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 Fixtures/TestProject/StandaloneFiles/Standalone.swift diff --git a/Fixtures/TestProject/App_iOS/AppDelegate.swift b/Fixtures/TestProject/App_iOS/AppDelegate.swift index bc2428a6..b32ceaee 100644 --- a/Fixtures/TestProject/App_iOS/AppDelegate.swift +++ b/Fixtures/TestProject/App_iOS/AppDelegate.swift @@ -18,6 +18,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. _ = FrameworkStruct() + // Standalone files added to project by path-to-file. + _ = standaloneHello() return true } diff --git a/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Fixtures/TestProject/Project.xcodeproj/project.pbxproj index 17276455..3af1b493 100644 --- a/Fixtures/TestProject/Project.xcodeproj/project.pbxproj +++ b/Fixtures/TestProject/Project.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ BF1073850101 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FR1332263601 /* AppDelegate.swift */; }; BF1401236301 /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FR3032072501 /* Alamofire.framework */; }; + BF1628293501 /* Standalone.swift in Sources */ = {isa = PBXBuildFile; fileRef = FR2554453101 /* Standalone.swift */; }; BF1744565901 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FR6218091901 /* ViewController.swift */; }; BF2018435801 /* Framework_iOS.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = FR4722960401 /* Framework_iOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; BF2250910101 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = VG2043127501 /* Main.storyboard */; }; @@ -70,6 +71,7 @@ FR1345298502 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; FR1345298503 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; FR1473702401 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + FR2554453101 /* Standalone.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Standalone.swift; sourceTree = ""; }; FR3032072501 /* Alamofire.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Alamofire.framework; sourceTree = ""; }; FR3032072502 /* Alamofire.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Alamofire.framework; sourceTree = ""; }; FR3032072503 /* Alamofire.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Alamofire.framework; sourceTree = ""; }; @@ -195,6 +197,15 @@ path = tvOS; sourceTree = ""; }; + G66512504301 /* StandaloneFiles */ = { + isa = PBXGroup; + children = ( + FR2554453101 /* Standalone.swift */, + ); + name = StandaloneFiles; + path = StandaloneFiles; + sourceTree = ""; + }; G67871650901 /* watchOS */ = { isa = PBXGroup; children = ( @@ -243,6 +254,7 @@ isa = PBXGroup; children = ( G83406189501 /* Configs */, + G66512504301 /* StandaloneFiles */, G82523211001 /* App_iOS */, G78312289901 /* App_iOS_Tests */, G46615002701 /* Framework */, @@ -620,6 +632,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + BF1628293501 /* Standalone.swift in Sources */, BF1073850101 /* AppDelegate.swift in Sources */, BF1744565901 /* ViewController.swift in Sources */, ); diff --git a/Fixtures/TestProject/StandaloneFiles/Standalone.swift b/Fixtures/TestProject/StandaloneFiles/Standalone.swift new file mode 100644 index 00000000..2062b15d --- /dev/null +++ b/Fixtures/TestProject/StandaloneFiles/Standalone.swift @@ -0,0 +1,3 @@ +func standaloneHello() -> String { + return "Hello" +} diff --git a/Fixtures/TestProject/spec.yml b/Fixtures/TestProject/spec.yml index 159e36df..9ad1ecad 100644 --- a/Fixtures/TestProject/spec.yml +++ b/Fixtures/TestProject/spec.yml @@ -10,7 +10,9 @@ targets: App_iOS: type: application platform: iOS - sources: App_iOS + sources: + - App_iOS + - StandaloneFiles/Standalone.swift settings: PRODUCT_BUNDLE_IDENTIFIER: com.project$(BUNDLE_ID_SUFFIX) INFOPLIST_FILE: App_iOS/Info.plist diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 62343187..b43a2bcd 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -66,7 +66,8 @@ public class PBXProjGenerator { for group in spec.fileGroups { //TODO: call a seperate function that only creates groups not source files - _ = try getSourceFiles(path: spec.basePath + group) + let path = spec.basePath + group + _ = try getSourceFiles(path: path, children: try path.children()) } let buildConfigs: [XCBuildConfiguration] = spec.configs.map { config in @@ -158,7 +159,7 @@ public class PBXProjGenerator { let carthageDependencies = getAllCarthageDependencies(target: target) - let sourceFiles = try target.sources.flatMap(getSourceFiles) + let sourceFiles = try getAllSourceFiles(sources: target.sources) // find all Info.plist files let infoPlists: [Path] = target.sources.map { spec.basePath + $0.path }.flatMap { (path) -> [Path] in @@ -490,26 +491,42 @@ public class PBXProjGenerator { return fileReference.reference } } + + func getAllSourceFiles(sources: [Source]) throws -> [SourceFile] { + let sourcePaths = sources.map{ spec.basePath + $0.path } - func getSourceFiles(source: Source) throws -> [SourceFile] { - //TODO: add support for source files as well as directories - return try getSourceFiles(path: spec.basePath + source.path, depth: 0).sourceFiles + let (files, dirs) = (sourcePaths.filter{ $0.isFile }, sourcePaths.filter{ $0.isDirectory }) + let filesByParent: [Path: [Path]] = files.reduce([:]) { acc, file in + var mut = acc + let group = file.parent() + mut[group, default: []].append(file) + return mut + } + + let fromFiles = try filesByParent.map{ parent, files in + try getSourceFiles(path: parent, children: files) + } + let fromDirs = try dirs.map{ dir in + try getSourceFiles(path: dir, children: try dir.children()) + } + + return (fromFiles + fromDirs).flatMap{ $0.sourceFiles } } - - func getSourceFiles(path: Path, depth: Int = 0) throws -> (sourceFiles: [SourceFile], groups: [PBXGroup]) { + + func getSourceFiles(path: Path, children: [Path], depth: Int = 0) throws -> (sourceFiles: [SourceFile], groups: [PBXGroup]) { let excludedFiles: [String] = [".DS_Store"] - let directories = try path.children() + let directories = children .filter { $0.isDirectory && $0.extension == nil && $0.extension != "lproj" } .sorted { $0.lastComponent < $1.lastComponent } - let filePaths = try path.children() + let filePaths = children .filter { $0.isFile || $0.extension != nil && $0.extension != "lproj" } .filter { !excludedFiles.contains($0.lastComponent) } .sorted { $0.lastComponent < $1.lastComponent } - let localisedDirectories = try path.children() + let localisedDirectories = children .filter { $0.extension == "lproj" } .sorted { $0.lastComponent < $1.lastComponent } @@ -518,7 +535,7 @@ public class PBXProjGenerator { var groups: [PBXGroup] = [] for path in directories { - let subGroups = try getSourceFiles(path: path, depth: depth + 1) + let subGroups = try getSourceFiles(path: path, children: try path.children(), depth: depth + 1) allSourceFiles += subGroups.sourceFiles groupChildren.append(subGroups.groups.first!.reference) groups += subGroups.groups