Skip to content

Commit 82e89b4

Browse files
committed
Merge branch 'develop' into feature/seralize
2 parents 0e5651c + 946a190 commit 82e89b4

File tree

6 files changed

+96
-22
lines changed

6 files changed

+96
-22
lines changed

Example/Example/main.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
import Foundation
1010

1111
// The xcodeproj file to load, test this with your own project!
12-
let xcodeproj = "Test.xcodeproj"
12+
let xcodeproj = NSURL(fileURLWithPath: "/Users/tom/Projects/Xcode.swift/Example/Test.xcodeproj")
1313

1414

1515
// Load from a xcodeproj
16-
let proj = try! XCProjectFile(xcodeprojPath: xcodeproj)
16+
let proj = try! XCProjectFile(xcodeprojURL: xcodeproj)
1717

1818
// Write out a new pbxproj file
19-
try! proj.writeToXcodeproj("/Users/tom/Projects/Xcode.swift/Example/" + xcodeproj)
19+
try! proj.writeToXcodeproj(xcodeprojURL: xcodeproj)
2020

2121
// Print paths for all files in Resources build phases
2222
for target in proj.project.targets {

LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2015 Tom Lokhorst
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
22+

README.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
1-
Xcode.swift
2-
===========
1+
<img src="https://cloud.githubusercontent.com/assets/75655/10141830/f92646ca-660e-11e5-8e1e-40c90482ead0.png" width="175" alt="Xcode.swift">
2+
<hr>
33

4-
Just playing around with the Xcode pbxproj file format.
4+
Reading the the Xcode pbxproj file format, from Swift!
55

6+
Currently, this project is mostly used to support [R.swift](https://github.com/mac-cain13/R.swift).
7+
8+
9+
Releases
10+
--------
11+
12+
- **0.1.0** - 2015-09-28 - Initial public release
13+
14+
15+
Licence & Credits
16+
-----------------
17+
18+
Xcode.swift is written by [Tom Lokhorst](https://twitter.com/tomlokhorst) and available under the [MIT license](https://github.com/tomlokhorst/Xcode.swift/blob/develop/LICENSE), so feel free to use it in commercial and non-commercial projects.
619

Xcode/Xcode/PBXObject.swift

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,13 @@ public class XCConfigurationList : PBXProjectItem {
115115
public class PBXReference : PBXContainerItem {
116116
public lazy var name: String? = self.string("name")
117117
public lazy var path: String? = self.string("path")
118+
public lazy var sourceTree: SourceTree = self.string("sourceTree").flatMap(SourceTree.init)!
118119
}
119120

120121
public class PBXFileReference : PBXReference {
121122

122123
// convenience accessor
123-
public lazy var fullPath: String = self.allObjects.fullFilePaths[self.id]!
124+
public lazy var fullPath: Path = self.allObjects.fullFilePaths[self.id]!
124125
}
125126

126127
public class PBXGroup : PBXReference {
@@ -136,3 +137,35 @@ public class PBXVariantGroup : PBXGroup {
136137

137138
public class XCVersionGroup : PBXReference {
138139
}
140+
141+
142+
public enum SourceTree {
143+
case Absolute
144+
case Group
145+
case RelativeTo(SourceTreeFolder)
146+
147+
init?(sourceTreeString: String) {
148+
switch sourceTreeString {
149+
case "<absolute>":
150+
self = .Absolute
151+
case "<group>":
152+
self = .Group
153+
default:
154+
guard let sourceTreeFolder = SourceTreeFolder(rawValue: sourceTreeString) else { return nil }
155+
self = .RelativeTo(sourceTreeFolder)
156+
}
157+
}
158+
}
159+
160+
public enum SourceTreeFolder: String {
161+
case SourceRoot = "SOURCE_ROOT"
162+
case BuildProductsDir = "BUILT_PRODUCTS_DIR"
163+
case DeveloperDir = "DEVELOPER_DIR"
164+
case SDKRoot = "SDKROOT"
165+
}
166+
167+
public enum Path {
168+
case Absolute(String)
169+
case RelativeTo(SourceTreeFolder, String)
170+
}
171+

Xcode/Xcode/Serialization.swift

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,22 @@ import Foundation
1010

1111
extension XCProjectFile {
1212

13-
public func writeToXcodeproj(xcodeprojPath: String) throws -> Bool {
13+
public func writeToXcodeproj(xcodeprojURL url: NSURL) throws -> Bool {
1414

15-
let url = NSURL(fileURLWithPath: xcodeprojPath, isDirectory: true)
1615
try NSFileManager.defaultManager().createDirectoryAtURL(url, withIntermediateDirectories: true, attributes: nil)
1716

18-
let name = try XCProjectFile.projectName(xcodeprojPath)
19-
let path = xcodeprojPath + "/project.pbxproj"
17+
let name = try XCProjectFile.projectName(url)
18+
let path = url.URLByAppendingPathComponent("project.pbxproj")
2019

2120
let serializer = Serializer(projectName: name, projectFile: self)
2221

2322
if format == NSPropertyListFormat.OpenStepFormat {
24-
try serializer.openStepSerialization.writeToFile(path, atomically: true, encoding: NSUTF8StringEncoding)
23+
try serializer.openStepSerialization.writeToURL(path, atomically: true, encoding: NSUTF8StringEncoding)
2524
return true
2625
}
2726
else {
2827
let data = try NSPropertyListSerialization.dataWithPropertyList(dict, format: format, options: 0)
29-
return data.writeToFile(path, atomically: true)
28+
return data.writeToURL(path, atomically: true)
3029
}
3130
}
3231

Xcode/Xcode/XCProjectFile.swift

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ enum ProjectFileError : ErrorType, CustomStringConvertible {
2727

2828
public class AllObjects {
2929
var dict: [String: PBXObject] = [:]
30-
var fullFilePaths: [String: String] = [:]
30+
var fullFilePaths: [String: Path] = [:]
3131

3232
func object<T : PBXObject>(key: String) -> T {
3333
let obj = dict[key]!
@@ -45,9 +45,10 @@ public class XCProjectFile {
4545
let format: NSPropertyListFormat
4646
let allObjects = AllObjects()
4747

48-
public convenience init(xcodeprojPath: String) throws {
48+
public convenience init(xcodeprojURL: NSURL) throws {
4949

50-
guard let data = NSData(contentsOfFile: xcodeprojPath + "/project.pbxproj") else {
50+
let pbxprojURL = xcodeprojURL.URLByAppendingPathComponent("project.pbxproj")
51+
guard let data = NSData(contentsOfURL: pbxprojURL) else {
5152
throw ProjectFileError.MissingPbxproj
5253
}
5354

@@ -82,9 +83,7 @@ public class XCProjectFile {
8283
self.allObjects.fullFilePaths = paths(self.project.mainGroup, prefix: "")
8384
}
8485

85-
static func projectName(xcodeprojPath: String) throws -> String {
86-
87-
let url = NSURL(fileURLWithPath: xcodeprojPath, isDirectory: true)
86+
static func projectName(url: NSURL) throws -> String {
8887

8988
guard let subpaths = url.pathComponents,
9089
let last = subpaths.last,
@@ -109,11 +108,19 @@ public class XCProjectFile {
109108
return PBXObject(id: id, dict: dict, allObjects: allObjects)
110109
}
111110

112-
func paths(current: PBXGroup, prefix: String) -> [String: String] {
113-
var ps: [String: String] = [:]
111+
func paths(current: PBXGroup, prefix: String) -> [String: Path] {
112+
113+
var ps: [String: Path] = [:]
114114

115115
for file in current.fileRefs {
116-
ps[file.id] = prefix + "/" + file.path!
116+
switch file.sourceTree {
117+
case .Group:
118+
ps[file.id] = .RelativeTo(.SourceRoot, prefix + "/" + file.path!)
119+
case .Absolute:
120+
ps[file.id] = .Absolute(file.path!)
121+
case let .RelativeTo(sourceTreeFolder):
122+
ps[file.id] = .RelativeTo(sourceTreeFolder, file.path!)
123+
}
117124
}
118125

119126
for group in current.subGroups {

0 commit comments

Comments
 (0)