Skip to content

Commit 0aa91f6

Browse files
authored
Merge pull request #6 from NativeScript/tdermendzhiev/fix-addpbxgroup
feature: Add groups created by addPbxGroup() to the meta PBXGroup
2 parents 08846bb + 93cb011 commit 0aa91f6

File tree

2 files changed

+144
-27
lines changed

2 files changed

+144
-27
lines changed

lib/pbxFile.js

+41-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
var path = require('path'),
1+
var $path = require('path'),
22
util = require('util'),
33
M_EXTENSION = /[.]m$/, SOURCE_FILE = 'sourcecode.c.objc',
4+
C_EXTENSION = /[.]c$/, C_SOURCE_FILE = 'sourcecode.c',
45
H_EXTENSION = /[.]h$/, HEADER_FILE = 'sourcecode.c.h',
6+
MM_EXTENSION = /[.]mm$/, MM_SOURCE_FILE = 'sourcecode.cpp.objcpp',
7+
HPP_EXTENSION = /[.](hpp|hxx|h\+\+|hh)$/, CPP_HEADER_FILE = 'sourcecode.cpp.h',
8+
CPP_EXTENSION = /[.](cpp|cxx|c\+\+|cc)$/, CPP_SOURCE_FILE = 'sourcecode.cpp.cpp',
59
BUNDLE_EXTENSION = /[.]bundle$/, BUNDLE = '"wrapper.plug-in"',
610
XIB_EXTENSION = /[.]xib$/, XIB_FILE = 'file.xib',
711
DYLIB_EXTENSION = /[.]dylib$/, DYLIB = '"compiled.mach-o.dylib"',
@@ -11,13 +15,42 @@ var path = require('path'),
1115
DEFAULT_SOURCE_TREE = '"<group>"',
1216
DEFAULT_FILE_ENCODING = 4;
1317

18+
function fileTypes() {
19+
return {
20+
SOURCE_FILE,
21+
C_SOURCE_FILE,
22+
HEADER_FILE,
23+
MM_SOURCE_FILE,
24+
CPP_HEADER_FILE,
25+
CPP_SOURCE_FILE,
26+
BUNDLE,
27+
XIB_FILE,
28+
FRAMEWORK,
29+
DYLIB,
30+
ARCHIVE,
31+
PNG_IMAGE,
32+
}
33+
}
34+
1435
function detectLastType(path) {
1536
if (M_EXTENSION.test(path))
1637
return SOURCE_FILE;
1738

39+
if (C_EXTENSION.test(path))
40+
return C_SOURCE_FILE;
41+
1842
if (H_EXTENSION.test(path))
1943
return HEADER_FILE;
2044

45+
if (MM_EXTENSION.test(path))
46+
return MM_SOURCE_FILE;
47+
48+
if (CPP_EXTENSION.test(path))
49+
return CPP_SOURCE_FILE;
50+
51+
if (HPP_EXTENSION.test(path))
52+
return CPP_HEADER_FILE;
53+
2154
if (BUNDLE_EXTENSION.test(path))
2255
return BUNDLE;
2356

@@ -82,17 +115,17 @@ function pbxFile(filepath, opt) {
82115
// for custom frameworks
83116
if(opt.customFramework == true) {
84117
this.customFramework = true;
85-
this.dirname = path.dirname(filepath);
118+
this.dirname = $path.dirname(filepath);
86119
}
87120

88-
this.basename = path.basename(filepath);
121+
this.basename = $path.basename(filepath);
89122
this.path = correctPath(this, filepath);
90123
this.group = correctGroup(this);
91124

92125
this.sourceTree = opt.sourceTree || defaultSourceTree(this);
93126
this.fileEncoding = opt.fileEncoding || fileEncoding(this);
94127

95-
if (opt.weak && opt.weak === true)
128+
if (opt.weak && opt.weak === true)
96129
this.settings = { ATTRIBUTES: ['Weak'] };
97130

98131
if (opt.compilerFlags) {
@@ -102,4 +135,7 @@ function pbxFile(filepath, opt) {
102135
}
103136
}
104137

105-
module.exports = pbxFile;
138+
module.exports = {
139+
pbxFile: pbxFile,
140+
fileTypes: fileTypes
141+
}

lib/pbxProject.js

+103-22
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
var util = require('util'),
22
f = util.format,
33
EventEmitter = require('events').EventEmitter,
4-
path = require('path'),
4+
$path = require('path'),
55
uuid = require('node-uuid'),
66
fork = require('child_process').fork,
77
pbxWriter = require('./pbxWriter'),
8-
pbxFile = require('./pbxFile'),
8+
pbxFile = require('./pbxFile').pbxFile,
9+
pbxFileTypes = require('./pbxFile').fileTypes,
910
fs = require('fs'),
1011
parser = require('./parser/pbxproj'),
1112
COMMENT_KEY = /_comment$/,
12-
NO_SPECIAL_SYMBOLS = /^[a-zA-Z0-9_\.\$]+\.[a-zA-Z]+$/;
13+
NO_SPECIAL_SYMBOLS = /^[a-zA-Z0-9_\.\$]+\.[a-zA-Z]+$/,
14+
HEADER_FILE_TYPE_SUFFIX = ".h",
15+
SOURCE_CODE_FILE_TYPE_PREFIX = "sourcecode.";
1316

1417
function pbxProject(filename) {
1518
if (!(this instanceof pbxProject))
1619
return new pbxProject(filename);
1720

18-
this.filepath = path.resolve(filename)
21+
this.filepath = $path.resolve(filename)
1922
}
2023

2124
util.inherits(pbxProject, EventEmitter)
@@ -286,31 +289,52 @@ pbxProject.prototype.removeFromPbxBuildFileSection = function (file) {
286289
}
287290
}
288291

289-
pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceTree) {
292+
pbxProject.prototype.findMainPbxGroup = function () {
293+
var groups = this.hash.project.objects['PBXGroup'];
294+
var candidates = [];
295+
for (var key in groups) {
296+
if (!groups[key].path && !groups[key].name && groups[key].isa) {
297+
candidates.push(groups[key]);
298+
}
299+
}
300+
if (candidates.length == 1) {
301+
return candidates[0];
302+
}
303+
304+
return null;
305+
}
306+
307+
pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceTree, opt) {
308+
309+
var oldGroup = this.pbxGroupByName(name);
310+
if (oldGroup) {
311+
this.removePbxGroup(name, path);
312+
}
313+
290314
var groups = this.hash.project.objects['PBXGroup'],
291-
pbxGroupUuid = this.generateUuid(),
315+
pbxGroupUuid = opt.uuid || this.generateUuid(),
292316
commentKey = f("%s_comment", pbxGroupUuid),
293317
pbxGroup = {
294318
isa: 'PBXGroup',
295319
children: [],
296320
name: name,
297-
path: path,
298321
sourceTree: sourceTree ? sourceTree : '"<group>"'
299-
},
322+
},//path is mandatory only for the main group
300323
fileReferenceSection = this.pbxFileReferenceSection(),
301324
filePathToReference = {};
302-
325+
303326
for (var key in fileReferenceSection) {
304327
// only look for comments
305328
if (!COMMENT_KEY.test(key)) continue;
306-
329+
307330
var fileReferenceKey = key.split(COMMENT_KEY)[0],
308331
fileReference = fileReferenceSection[fileReferenceKey];
309-
332+
310333
filePathToReference[fileReference.path] = {fileRef: fileReferenceKey, basename: fileReferenceSection[key]};
311334
}
312335

313336
for (var index = 0; index < filePathsArray.length; index++) {
337+
314338
var filePath = filePathsArray[index],
315339
filePathQuoted = "\"" + filePath + "\"";
316340
if (filePathToReference[filePath]) {
@@ -320,23 +344,80 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT
320344
pbxGroup.children.push(pbxGroupChild(filePathToReference[filePathQuoted]));
321345
continue;
322346
}
323-
324-
var file = new pbxFile(filePath);
325-
file.uuid = this.generateUuid();
326-
file.fileRef = this.generateUuid();
327-
this.addToPbxFileReferenceSection(file); // PBXFileReference
328-
this.addToPbxBuildFileSection(file); // PBXBuildFile
329-
pbxGroup.children.push(pbxGroupChild(file));
347+
348+
var srcRootPath = $path.dirname($path.dirname(this.filepath));
349+
var file = new pbxFile($path.relative(srcRootPath, filePath));
350+
if (fs.lstatSync(filePath).isDirectory()) {
351+
file.uuid = this.generateUuid();
352+
file.fileRef = file.uuid;
353+
this.addToPbxFileReferenceSection(file); // PBXFileReference
354+
this.addToPbxBuildFileSection(file);
355+
pbxGroup.children.push(pbxGroupChild(file));
356+
var files = fs.readdirSync(filePath).map(p => $path.join(filePath, p));
357+
this.addPbxGroup(files, $path.basename(filePath), filePath, null, {uuid: file.uuid});
358+
}else if (file.lastType.startsWith(SOURCE_CODE_FILE_TYPE_PREFIX)) {
359+
file.uuid = this.generateUuid();
360+
file.fileRef = this.generateUuid();
361+
this.addToPbxFileReferenceSection(file); // PBXFileReference
362+
this.addToPbxBuildFileSection(file); // PBXBuildFile
363+
if (!file.lastType.endsWith(HEADER_FILE_TYPE_SUFFIX)) {
364+
this.addToPbxSourcesBuildPhase(file);
365+
}
366+
pbxGroup.children.push(pbxGroupChild(file));
367+
}
368+
330369
}
331-
370+
332371
if (groups) {
333372
groups[pbxGroupUuid] = pbxGroup;
334373
groups[commentKey] = name;
335374
}
336-
375+
376+
if (opt.isMain) {
377+
let mainGroup = this.findMainPbxGroup();
378+
if (mainGroup) {
379+
var file = new pbxFile($path.relative(this.filepath, path));
380+
file.fileRef = pbxGroupUuid;
381+
mainGroup.children.push(pbxGroupChild(file));
382+
}
383+
}
384+
337385
return {uuid: pbxGroupUuid, pbxGroup: pbxGroup};
338386
}
339387

388+
pbxProject.prototype.removePbxGroup = function(name, path) {
389+
var group = this.pbxGroupByName(name);
390+
if (!group) {
391+
return;
392+
}
393+
394+
var children = group.children;
395+
396+
for(i in children) {
397+
var file = new pbxFile($path.join(path, children[i].comment));
398+
file.fileRef = children[i].value;
399+
file.uuid = file.fileRef;
400+
this.removePbxGroup(children[i].comment, $path.join(path, children[i].comment));
401+
this.removeFromPbxFileReferenceSection(file);
402+
this.removeFromPbxBuildFileSection(file);
403+
this.removeFromPbxSourcesBuildPhase(file);
404+
}
405+
406+
//copied from https://github.com/alunny/node-xcode/blob/master/lib/pbxProject.js#L527
407+
var section = this.hash.project.objects['PBXGroup'],
408+
key, itemKey;
409+
410+
for (key in section) {
411+
// only look for comments
412+
if (!COMMENT_KEY.test(key)) continue;
413+
414+
if (section[key] == name) {
415+
itemKey = key.split(COMMENT_KEY)[0];
416+
delete section[itemKey];
417+
}
418+
}
419+
}
420+
340421
pbxProject.prototype.addToPbxFileReferenceSection = function (file) {
341422
var commentKey = f("%s_comment", file.fileRef);
342423

@@ -852,7 +933,7 @@ pbxProject.prototype.removeFromHeaderSearchPaths = function (file) {
852933
INHERITED = '"$(inherited)"',
853934
SEARCH_PATHS = 'HEADER_SEARCH_PATHS',
854935
config, buildSettings, searchPaths;
855-
var new_path = searchPathForFile(file, this);
936+
var new_path = typeof file === 'string' ? file : searchPathForFile(file, this);
856937

857938
for (config in configurations) {
858939
buildSettings = configurations[config].buildSettings;
@@ -1048,7 +1129,7 @@ function searchPathForFile(file, proj) {
10481129

10491130
var plugins = proj.pbxGroupByName('Plugins'),
10501131
pluginsPath = plugins ? plugins.path : null,
1051-
fileDir = path.dirname(file.path);
1132+
fileDir = $path.dirname(file.path);
10521133

10531134
if (fileDir == '.') {
10541135
fileDir = '';

0 commit comments

Comments
 (0)