Skip to content

Commit 920b7c6

Browse files
committed
[pbxProject] addSourceFile
a lot of groundwork - addResourceFile and addHeaderFile will be a lot smaller
1 parent 0a4a717 commit 920b7c6

File tree

4 files changed

+288
-4
lines changed

4 files changed

+288
-4
lines changed

lib/pbxFile.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ var path = require('path'),
33
H_EXTENSION = /[.]h$/, HEADER_FILE = 'sourcecode.c.h',
44
BUNDLE_EXTENSION = /[.]bundle$/, BUNDLE = '"wrapper.plug-in"',
55
XIB_EXTENSION = /[.]xib$/, XIB_FILE = 'file.xib',
6-
DEFAULT_SOURCE_TREE = '"<group>"'
6+
DEFAULT_SOURCE_TREE = '"<group>"',
7+
DEFAULT_FILE_ENCODING = 4;
78

89
function detectLastType(path) {
910
if (M_EXTENSION.test(path))
@@ -25,6 +26,7 @@ function detectLastType(path) {
2526
function pbxFile(filepath, opt) {
2627
var opt = opt || {};
2728

29+
this.path = filepath;
2830
this.lastType = opt.lastType || detectLastType(filepath);
2931
this.basename = path.basename(filepath);
3032

@@ -35,6 +37,7 @@ function pbxFile(filepath, opt) {
3537
}
3638

3739
this.sourceTree = opt.sourceTree || DEFAULT_SOURCE_TREE;
40+
this.fileEncoding = opt.fileEncoding || DEFAULT_FILE_ENCODING;
3841
}
3942

4043
module.exports = pbxFile;

lib/pbxProject.js

Lines changed: 152 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
var util = require('util'),
2+
f = util.format,
23
EventEmitter = require('events').EventEmitter,
34
path = require('path'),
45
uuid = require('node-uuid'),
56
fork = require('child_process').fork,
6-
pbxWriter = require('./pbxWriter')
7+
pbxWriter = require('./pbxWriter'),
8+
pbxFile = require('./pbxFile'),
9+
COMMENT_KEY = /_comment$/
710

811
function pbxProject(filename) {
912
this.filepath = path.resolve(filename)
@@ -35,8 +38,7 @@ pbxProject.prototype.writeSync = function () {
3538
}
3639

3740
pbxProject.prototype.allUuids = function () {
38-
var COMMENT_KEY = /_comment$/,
39-
sections = this.hash.project.objects,
41+
var sections = this.hash.project.objects,
4042
uuids = [],
4143
section;
4244

@@ -65,4 +67,151 @@ pbxProject.prototype.generateUuid = function () {
6567
}
6668
}
6769

70+
pbxProject.prototype.addSourceFile = function (path, opt) {
71+
var file = new pbxFile(path, opt),
72+
commentKey, pluginsGroup, sources;
73+
74+
file.uuid = this.generateUuid();
75+
file.fileRef = this.generateUuid();
76+
77+
// PBXBuildFile
78+
commentKey = f("%s_comment", file.uuid);
79+
80+
this.pbxBuildFileSection()[file.uuid] = pbxBuildFileObj(file);
81+
this.pbxBuildFileSection()[commentKey] = pbxBuildFileComment(file);
82+
83+
// PBXFileReference
84+
commentKey = f("%s_comment", file.fileRef);
85+
86+
this.pbxFileReferenceSection()[file.fileRef] = pbxFileReferenceObj(file);
87+
this.pbxFileReferenceSection()[commentKey] = pbxFileReferenceComment(file);
88+
89+
// PBXGroup
90+
pluginsGroup = this.pbxGroupByName('Plugins');
91+
pluginsGroup.children.push(pbxGroupChild(file));
92+
93+
// PBXSourcesBuildPhase
94+
sources = this.pbxSourcesBuildPhaseObj();
95+
sources.files.push(pbxSourceFileObj(file));
96+
97+
return file;
98+
}
99+
100+
pbxProject.prototype.addHeaderFile = function (path, opt) {
101+
/*
102+
* PBXFileReference
103+
* PBXGroup (Plugins)
104+
*/
105+
}
106+
107+
pbxProject.prototype.addResourceFile = function (path, opt) {
108+
/*
109+
* PBXBuildFile
110+
* PBXFileReference
111+
* PBXGroup (Plugins)
112+
* PBXResourcesBuildPhase
113+
*/
114+
}
115+
116+
// helper access functions
117+
pbxProject.prototype.pbxBuildFileSection = function () {
118+
return this.hash.project.objects['PBXBuildFile'];
119+
}
120+
121+
pbxProject.prototype.pbxFileReferenceSection = function () {
122+
return this.hash.project.objects['PBXFileReference'];
123+
}
124+
125+
pbxProject.prototype.pbxGroupByName = function (name) {
126+
var groups = this.hash.project.objects['PBXGroup'],
127+
key, groupKey;
128+
129+
for (key in groups) {
130+
// only look for comments
131+
if (!COMMENT_KEY.test(key)) continue;
132+
133+
if (groups[key] == name) {
134+
groupKey = key.split(COMMENT_KEY)[0];
135+
return groups[groupKey];
136+
}
137+
}
138+
139+
return null;
140+
}
141+
142+
pbxProject.prototype.pbxSourcesBuildPhaseSection = function () {
143+
return this.hash.project.objects['PBXSourcesBuildPhase'];
144+
}
145+
146+
pbxProject.prototype.pbxSourcesBuildPhaseObj = function () {
147+
var section = this.pbxSourcesBuildPhaseSection(),
148+
obj, sectionKey;
149+
150+
for (key in section) {
151+
// only look for comments
152+
if (!COMMENT_KEY.test(key)) continue;
153+
154+
if (section[key] == 'Sources') {
155+
sectionKey = key.split(COMMENT_KEY)[0];
156+
return section[sectionKey];
157+
}
158+
}
159+
160+
return null;
161+
}
162+
163+
// helper object creation functions
164+
function pbxBuildFileObj(file) {
165+
var obj = Object.create(null);
166+
167+
obj.isa = 'PBXBuildFile';
168+
obj.fileRef = file.fileRef;
169+
obj.fileRef_comment = file.basename;
170+
171+
return obj;
172+
}
173+
174+
function pbxFileReferenceObj(file) {
175+
var obj = Object.create(null);
176+
177+
obj.isa = 'PBXFileReference';
178+
obj.fileEncoding = file.fileEncoding;
179+
obj.lastKnownFileType = file.lastType;
180+
obj.name = file.basename;
181+
obj.path = file.path;
182+
obj.sourceTree = file.sourceTree;
183+
184+
return obj;
185+
}
186+
187+
function pbxGroupChild(file) {
188+
var obj = Object.create(null);
189+
190+
obj.value = file.fileRef;
191+
obj.comment = file.basename;
192+
193+
return obj;
194+
}
195+
196+
function pbxSourceFileObj(file) {
197+
var obj = Object.create(null);
198+
199+
obj.value = file.uuid;
200+
obj.comment = longComment(file);
201+
202+
return obj;
203+
}
204+
205+
function pbxBuildFileComment(file) {
206+
return longComment(file);
207+
}
208+
209+
function pbxFileReferenceComment(file) {
210+
return file.basename;
211+
}
212+
213+
function longComment(file) {
214+
return f("%s in %s", file.basename, file.group);
215+
}
216+
68217
module.exports = pbxProject;

test/addSourceFile.js

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
var fullProject = require('./fixtures/full-project')
2+
fullProjectStr = JSON.stringify(fullProject),
3+
pbx = require('../lib/pbxProject'),
4+
pbxFile = require('../lib/pbxFile'),
5+
proj = new pbx('.');
6+
7+
function cleanHash() {
8+
return JSON.parse(fullProjectStr);
9+
}
10+
11+
exports.setUp = function (callback) {
12+
proj.hash = cleanHash();
13+
callback();
14+
}
15+
16+
exports.addSourceFile = {
17+
'should return a pbxFile': function (test) {
18+
var newFile = proj.addSourceFile('file.m');
19+
20+
test.equal(newFile.constructor, pbxFile);
21+
test.done()
22+
},
23+
'should set a uuid on the pbxFile': function (test) {
24+
var newFile = proj.addSourceFile('file.m');
25+
26+
test.ok(newFile.uuid);
27+
test.done()
28+
},
29+
'should set a fileRef on the pbxFile': function (test) {
30+
var newFile = proj.addSourceFile('file.m');
31+
32+
test.ok(newFile.fileRef);
33+
test.done()
34+
},
35+
'should populate the PBXBuildFile section with 2 fields': function (test) {
36+
var newFile = proj.addSourceFile('file.m'),
37+
buildFileSection = proj.pbxBuildFileSection(),
38+
bfsLength = Object.keys(buildFileSection).length;
39+
40+
test.equal(60, bfsLength);
41+
test.ok(buildFileSection[newFile.uuid]);
42+
test.ok(buildFileSection[newFile.uuid + '_comment']);
43+
44+
test.done();
45+
},
46+
'should add the PBXBuildFile comment correctly': function (test) {
47+
var newFile = proj.addSourceFile('file.m'),
48+
commentKey = newFile.uuid + '_comment',
49+
buildFileSection = proj.pbxBuildFileSection();
50+
51+
test.equal(buildFileSection[commentKey], 'file.m in Sources');
52+
test.done();
53+
},
54+
'should add the PBXBuildFile object correctly': function (test) {
55+
var newFile = proj.addSourceFile('file.m'),
56+
buildFileSection = proj.pbxBuildFileSection(),
57+
buildFileEntry = buildFileSection[newFile.uuid];
58+
59+
test.equal(buildFileEntry.isa, 'PBXBuildFile');
60+
test.equal(buildFileEntry.fileRef, newFile.fileRef);
61+
test.equal(buildFileEntry.fileRef_comment, 'file.m');
62+
63+
test.done();
64+
},
65+
'should populate the PBXFileReference section with 2 fields': function (test) {
66+
var newFile = proj.addSourceFile('file.m'),
67+
fileRefSection = proj.pbxFileReferenceSection(),
68+
frsLength = Object.keys(fileRefSection).length;
69+
70+
test.equal(68, frsLength);
71+
test.ok(fileRefSection[newFile.fileRef]);
72+
test.ok(fileRefSection[newFile.fileRef + '_comment']);
73+
74+
test.done();
75+
},
76+
'should populate the PBXFileReference comment correctly': function (test) {
77+
var newFile = proj.addSourceFile('file.m'),
78+
fileRefSection = proj.pbxFileReferenceSection(),
79+
commentKey = newFile.fileRef + '_comment';
80+
81+
test.equal(fileRefSection[commentKey], 'file.m');
82+
test.done();
83+
},
84+
'should add the PBXFileReference object correctly': function (test) {
85+
var newFile = proj.addSourceFile('Plugins/file.m'),
86+
fileRefSection = proj.pbxFileReferenceSection(),
87+
fileRefEntry = fileRefSection[newFile.fileRef];
88+
89+
test.equal(fileRefEntry.isa, 'PBXFileReference');
90+
test.equal(fileRefEntry.fileEncoding, 4);
91+
test.equal(fileRefEntry.lastKnownFileType, 'sourcecode.c.objc');
92+
test.equal(fileRefEntry.name, 'file.m');
93+
test.equal(fileRefEntry.path, 'Plugins/file.m');
94+
test.equal(fileRefEntry.sourceTree, '"<group>"');
95+
96+
test.done();
97+
},
98+
'should add to the Plugins PBXGroup group': function (test) {
99+
var newFile = proj.addSourceFile('Plugins/file.m'),
100+
plugins = proj.pbxGroupByName('Plugins');
101+
102+
test.equal(plugins.children.length, 1);
103+
test.done();
104+
},
105+
'should have the right values for the PBXGroup entry': function (test) {
106+
var newFile = proj.addSourceFile('Plugins/file.m'),
107+
plugins = proj.pbxGroupByName('Plugins'),
108+
pluginObj = plugins.children[0];
109+
110+
test.equal(pluginObj.comment, 'file.m');
111+
test.equal(pluginObj.value, newFile.fileRef);
112+
test.done();
113+
},
114+
'should add to the PBXSourcesBuildPhase': function (test) {
115+
var newFile = proj.addSourceFile('Plugins/file.m'),
116+
sources = proj.pbxSourcesBuildPhaseObj();
117+
118+
test.equal(sources.files.length, 3);
119+
test.done();
120+
},
121+
'should have the right values for the Sources entry': function (test) {
122+
var newFile = proj.addSourceFile('Plugins/file.m'),
123+
sources = proj.pbxSourcesBuildPhaseObj(),
124+
sourceObj = sources.files[2];
125+
126+
test.equal(sourceObj.comment, 'file.m in Sources');
127+
test.equal(sourceObj.value, newFile.uuid);
128+
test.done();
129+
}
130+
}
131+

0 commit comments

Comments
 (0)