Merge branch 'upstream/master'
# Conflicts:
# lib/pbxProject.js
diff --git a/lib/parseJob.js b/lib/parseJob.js
index 804be10..9d6bffa 100644
--- a/lib/parseJob.js
+++ b/lib/parseJob.js
@@ -6,11 +6,10 @@
fileContents, obj;
try {
- fileContents = fs.readFileSync(path, 'utf-8'),
- obj = parser.parse(fileContents)
- process.send(obj)
- process.exit()
+ fileContents = fs.readFileSync(path, 'utf-8');
+ obj = parser.parse(fileContents);
+ process.send(obj);
} catch (e) {
- process.send(e)
- process.exit(1)
+ process.send(e);
+ process.exitCode = 1;
}
diff --git a/lib/pbxFile.js b/lib/pbxFile.js
index 887f6e6..4431f0d 100644
--- a/lib/pbxFile.js
+++ b/lib/pbxFile.js
@@ -1,100 +1,193 @@
var path = require('path'),
- util = require('util'),
- M_EXTENSION = /[.]m$/, SOURCE_FILE = 'sourcecode.c.objc',
- H_EXTENSION = /[.]h$/, HEADER_FILE = 'sourcecode.c.h',
- BUNDLE_EXTENSION = /[.]bundle$/, BUNDLE = '"wrapper.plug-in"',
- XIB_EXTENSION = /[.]xib$/, XIB_FILE = 'file.xib',
- DYLIB_EXTENSION = /[.]dylib$/, DYLIB = '"compiled.mach-o.dylib"',
- FRAMEWORK_EXTENSION = /[.]framework$/, FRAMEWORK = 'wrapper.framework',
- ARCHIVE_EXTENSION = /[.]a$/, ARCHIVE = 'archive.ar',
- DEFAULT_SOURCE_TREE = '"<group>"',
- DEFAULT_FILE_ENCODING = 4;
+ util = require('util');
-function detectLastType(path) {
- if (M_EXTENSION.test(path))
- return SOURCE_FILE;
+var DEFAULT_SOURCETREE = '"<group>"',
+ DEFAULT_PRODUCT_SOURCETREE = 'BUILT_PRODUCTS_DIR',
+ DEFAULT_FILEENCODING = 4,
+ DEFAULT_GROUP = 'Resources',
+ DEFAULT_FILETYPE = 'unknown';
- if (H_EXTENSION.test(path))
- return HEADER_FILE;
+var FILETYPE_BY_EXTENSION = {
+ a: 'archive.ar',
+ app: 'wrapper.application',
+ appex: 'wrapper.app-extension',
+ bundle: 'wrapper.plug-in',
+ dylib: 'compiled.mach-o.dylib',
+ framework: 'wrapper.framework',
+ h: 'sourcecode.c.h',
+ m: 'sourcecode.c.objc',
+ markdown: 'text',
+ mdimporter: 'wrapper.cfbundle',
+ octest: 'wrapper.cfbundle',
+ pch: 'sourcecode.c.h',
+ plist: 'text.plist.xml',
+ sh: 'text.script.sh',
+ swift: 'sourcecode.swift',
+ xcassets: 'folder.assetcatalog',
+ xcconfig: 'text.xcconfig',
+ xcdatamodel: 'wrapper.xcdatamodel',
+ xcodeproj: 'wrapper.pb-project',
+ xctest: 'wrapper.cfbundle',
+ xib: 'file.xib'
+ },
+ GROUP_BY_FILETYPE = {
+ 'archive.ar': 'Frameworks',
+ 'compiled.mach-o.dylib': 'Frameworks',
+ 'wrapper.framework': 'Frameworks',
+ 'sourcecode.c.h': 'Resources',
+ 'sourcecode.c.objc': 'Sources',
+ 'sourcecode.swift': 'Sources'
+ },
+ PATH_BY_FILETYPE = {
+ 'compiled.mach-o.dylib': 'usr/lib/',
+ 'wrapper.framework': 'System/Library/Frameworks/'
+ },
+ SOURCETREE_BY_FILETYPE = {
+ 'compiled.mach-o.dylib': 'SDKROOT',
+ 'wrapper.framework': 'SDKROOT'
+ },
+ ENCODING_BY_FILETYPE = {
+ 'sourcecode.c.h': 4,
+ 'sourcecode.c.h': 4,
+ 'sourcecode.c.objc': 4,
+ 'sourcecode.swift': 4,
+ 'text': 4,
+ 'text.plist.xml': 4,
+ 'text.script.sh': 4,
+ 'text.xcconfig': 4
+ };
- if (BUNDLE_EXTENSION.test(path))
- return BUNDLE;
- if (XIB_EXTENSION.test(path))
- return XIB_FILE;
-
- if (FRAMEWORK_EXTENSION.test(path))
- return FRAMEWORK;
-
- if (DYLIB_EXTENSION.test(path))
- return DYLIB;
-
- if (ARCHIVE_EXTENSION.test(path))
- return ARCHIVE;
-
- // dunno
- return 'unknown';
+function unquoted(text){
+ return text.replace (/(^")|("$)/g, '')
}
-function fileEncoding(file) {
- if (file.lastType != BUNDLE && !file.customFramework) {
- return DEFAULT_FILE_ENCODING;
+function detectType(filePath) {
+ var extension = path.extname(filePath).substring(1),
+ filetype = FILETYPE_BY_EXTENSION[unquoted(extension)];
+
+ if (!filetype) {
+ return DEFAULT_FILETYPE;
+ }
+
+ return filetype;
+}
+
+function defaultExtension(fileRef) {
+ var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType;
+
+ for(var extension in FILETYPE_BY_EXTENSION) {
+ if(FILETYPE_BY_EXTENSION.hasOwnProperty(unquoted(extension)) ) {
+ if(FILETYPE_BY_EXTENSION[unquoted(extension)] === filetype )
+ return extension;
+ }
}
}
-function defaultSourceTree(file) {
- if (( file.lastType == DYLIB || file.lastType == FRAMEWORK ) && !file.customFramework) {
- return 'SDKROOT';
- } else {
- return DEFAULT_SOURCE_TREE;
+function defaultEncoding(fileRef) {
+ var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType,
+ encoding = ENCODING_BY_FILETYPE[unquoted(filetype)];
+
+ if (encoding) {
+ return encoding;
}
}
-function correctPath(file, filepath) {
- if (file.lastType == FRAMEWORK && !file.customFramework) {
- return 'System/Library/Frameworks/' + filepath;
- } else if (file.lastType == DYLIB) {
- return 'usr/lib/' + filepath;
- } else {
- return filepath;
+function detectGroup(fileRef) {
+ var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType,
+ groupName = GROUP_BY_FILETYPE[unquoted(filetype)];
+
+ if (!groupName) {
+ return DEFAULT_GROUP;
}
+
+ return groupName;
}
-function correctGroup(file) {
- if (file.lastType == SOURCE_FILE) {
- return 'Sources';
- } else if (file.lastType == DYLIB || file.lastType == ARCHIVE || file.lastType == FRAMEWORK) {
- return 'Frameworks';
- } else {
- return 'Resources';
+function detectSourcetree(fileRef) {
+
+ var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType,
+ sourcetree = SOURCETREE_BY_FILETYPE[unquoted(filetype)];
+
+ if (fileRef.explicitFileType) {
+ return DEFAULT_PRODUCT_SOURCETREE;
}
+
+ if (fileRef.customFramework) {
+ return DEFAULT_SOURCETREE;
+ }
+
+ if (!sourcetree) {
+ return DEFAULT_SOURCETREE;
+ }
+
+ return sourcetree;
+}
+
+function defaultPath(fileRef, filePath) {
+ var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType,
+ defaultPath = PATH_BY_FILETYPE[unquoted(filetype)];
+
+ if (fileRef.customFramework) {
+ return filePath;
+ }
+
+ if (defaultPath) {
+ return path.join(defaultPath, path.basename(filePath));
+ }
+
+ return filePath;
+}
+
+function defaultGroup(fileRef) {
+ var groupName = GROUP_BY_FILETYPE[fileRef.lastKnownFileType];
+
+ if (!groupName) {
+ return DEFAULT_GROUP;
+ }
+
+ return defaultGroup;
}
function pbxFile(filepath, opt) {
var opt = opt || {};
+
+ self = this;
- this.lastType = opt.lastType || detectLastType(filepath);
+ this.lastKnownFileType = opt.lastKnownFileType || detectType(filepath);
+ this.group = detectGroup(self);
// for custom frameworks
- if(opt.customFramework == true) {
- this.customFramework = true;
- this.dirname = path.dirname(filepath);
+ if (opt.customFramework == true) {
+ this.customFramework = true;
+ this.dirname = path.dirname(filepath);
}
this.basename = path.basename(filepath);
- this.path = correctPath(this, filepath);
- this.group = correctGroup(this);
+ this.path = defaultPath(this, filepath);
+ this.fileEncoding = this.defaultEncoding = opt.defaultEncoding || defaultEncoding(self);
- this.sourceTree = opt.sourceTree || defaultSourceTree(this);
- this.fileEncoding = opt.fileEncoding || fileEncoding(this);
- if (opt.weak && opt.weak === true)
- this.settings = { ATTRIBUTES: ['Weak'] };
+ // When referencing products / build output files
+ if (opt.explicitFileType) {
+ this.explicitFileType = opt.explicitFileType;
+ this.basename = this.basename + '.' + defaultExtension(this);
+ delete this.path;
+ delete this.lastKnownFileType;
+ delete this.group;
+ delete this.defaultEncoding;
+ }
+
+ this.sourceTree = opt.sourceTree || detectSourcetree(self);
+ this.includeInIndex = 0;
+
+ if (opt.weak && opt.weak === true)
+ this.settings = { ATTRIBUTES: ['Weak'] };
if (opt.compilerFlags) {
if (!this.settings)
- this.settings = {};
- this.settings.COMPILER_FLAGS = util.format('"%s"', opt.compilerFlags);
+ this.settings = {};
+ this.settings.COMPILER_FLAGS = util.format('"%s"', opt.compilerFlags);
}
}
diff --git a/lib/pbxProject.js b/lib/pbxProject.js
index 4d9ecb4..92c6886 100644
--- a/lib/pbxProject.js
+++ b/lib/pbxProject.js
@@ -19,10 +19,10 @@
util.inherits(pbxProject, EventEmitter)
-pbxProject.prototype.parse = function (cb) {
+pbxProject.prototype.parse = function(cb) {
var worker = fork(__dirname + '/parseJob.js', [this.filepath])
- worker.on('message', function (msg) {
+ worker.on('message', function(msg) {
if (msg.name == 'SyntaxError' || msg.code) {
this.emit('error', msg);
} else {
@@ -39,19 +39,19 @@
return this;
}
-pbxProject.prototype.parseSync = function () {
+pbxProject.prototype.parseSync = function() {
var file_contents = fs.readFileSync(this.filepath, 'utf-8');
this.hash = parser.parse(file_contents);
return this;
}
-pbxProject.prototype.writeSync = function () {
+pbxProject.prototype.writeSync = function() {
this.writer = new pbxWriter(this.hash);
return this.writer.writeSync();
}
-pbxProject.prototype.allUuids = function () {
+pbxProject.prototype.allUuids = function() {
var sections = this.hash.project.objects,
uuids = [],
section;
@@ -61,18 +61,18 @@
uuids = uuids.concat(Object.keys(section))
}
- uuids = uuids.filter(function (str) {
+ uuids = uuids.filter(function(str) {
return !COMMENT_KEY.test(str) && str.length == 24;
});
return uuids;
}
-pbxProject.prototype.generateUuid = function () {
+pbxProject.prototype.generateUuid = function() {
var id = uuid.v4()
- .replace(/-/g,'')
- .substr(0,24)
- .toUpperCase()
+ .replace(/-/g, '')
+ .substr(0, 24)
+ .toUpperCase()
if (this.allUuids().indexOf(id) >= 0) {
return this.generateUuid();
@@ -81,7 +81,7 @@
}
}
-pbxProject.prototype.addPluginFile = function (path, opt) {
+pbxProject.prototype.addPluginFile = function(path, opt) {
var file = new pbxFile(path, opt);
file.plugin = true; // durr
@@ -98,7 +98,7 @@
return file;
}
-pbxProject.prototype.removePluginFile = function (path, opt) {
+pbxProject.prototype.removePluginFile = function(path, opt) {
var file = new pbxFile(path, opt);
correctForPluginsPath(file, this);
@@ -108,10 +108,46 @@
return file;
}
+pbxProject.prototype.addProductFile = function(targetPath, opt) {
+ var file = new pbxFile(targetPath, opt);
-pbxProject.prototype.addSourceFile = function (path, opt) {
-
- var file = this.addPluginFile(path, opt);
+ file.includeInIndex = 0;
+ file.fileRef = this.generateUuid();
+ file.target = opt ? opt.target : undefined;
+ file.group = opt ? opt.group : undefined;
+ file.uuid = this.generateUuid();
+ file.path = file.basename;
+
+ this.addToPbxFileReferenceSection(file);
+ this.addToProductsPbxGroup(file); // PBXGroup
+
+ return file;
+}
+
+pbxProject.prototype.removeProductFile = function(path, opt) {
+ var file = new pbxFile(path, opt);
+
+ this.removeFromProductsPbxGroup(file); // PBXGroup
+
+ return file;
+}
+
+/**
+ *
+ * @param path {String}
+ * @param opt {Object} see pbxFile for avail options
+ * @param group {String} group key
+ * @returns {Object} file; see pbxFile
+ */
+pbxProject.prototype.addSourceFile = function (path, opt, group) {
+ var file;
+ if (group) {
+ file = this.addFile(path, group, opt);
+ }
+ else {
+ file = this.addPluginFile(path, opt);
+ }
+
if (!file) return false;
file.target = opt ? opt.target : undefined;
@@ -123,9 +159,21 @@
return file;
}
-
-pbxProject.prototype.removeSourceFile = function (path, opt) {
- var file = this.removePluginFile(path, opt)
+/**
+ *
+ * @param path {String}
+ * @param opt {Object} see pbxFile for avail options
+ * @param group {String} group key
+ * @returns {Object} file; see pbxFile
+ */
+pbxProject.prototype.removeSourceFile = function (path, opt, group) {
+ var file;
+ if (group) {
+ file = this.removeFile(path, group, opt);
+ }
+ else {
+ file = this.removePluginFile(path, opt);
+ }
file.target = opt ? opt.target : undefined;
this.removeFromPbxBuildFileSection(file); // PBXBuildFile
this.removeFromPbxSourcesBuildPhase(file); // PBXSourcesBuildPhase
@@ -133,15 +181,39 @@
return file;
}
-pbxProject.prototype.addHeaderFile = function (path, opt) {
- return this.addPluginFile(path, opt)
+/**
+ *
+ * @param path {String}
+ * @param opt {Object} see pbxFile for avail options
+ * @param group {String} group key
+ * @returns {Object} file; see pbxFile
+ */
+pbxProject.prototype.addHeaderFile = function (path, opt, group) {
+ if (group) {
+ return this.addFile(path, group, opt);
+ }
+ else {
+ return this.addPluginFile(path, opt);
+ }
}
-pbxProject.prototype.removeHeaderFile = function (path, opt) {
- return this.removePluginFile(path, opt)
+/**
+ *
+ * @param path {String}
+ * @param opt {Object} see pbxFile for avail options
+ * @param group {String} group key
+ * @returns {Object} file; see pbxFile
+ */
+pbxProject.prototype.removeHeaderFile = function (path, opt, group) {
+ if (group) {
+ return this.removeFile(path, group, opt);
+ }
+ else {
+ return this.removePluginFile(path, opt);
+ }
}
-pbxProject.prototype.addResourceFile = function (path, opt) {
+pbxProject.prototype.addResourceFile = function(path, opt) {
opt = opt || {};
var file;
@@ -173,43 +245,43 @@
return file;
}
-pbxProject.prototype.removeResourceFile = function (path, opt) {
+pbxProject.prototype.removeResourceFile = function(path, opt) {
var file = new pbxFile(path, opt);
file.target = opt ? opt.target : undefined;
-
+
correctForResourcesPath(file, this);
this.removeFromPbxBuildFileSection(file); // PBXBuildFile
this.removeFromPbxFileReferenceSection(file); // PBXFileReference
this.removeFromResourcesPbxGroup(file); // PBXGroup
this.removeFromPbxResourcesBuildPhase(file); // PBXResourcesBuildPhase
-
+
return file;
}
-pbxProject.prototype.addFramework = function (fpath, opt) {
+pbxProject.prototype.addFramework = function(fpath, opt) {
+
var file = new pbxFile(fpath, opt);
- // catch duplicates
- if (this.hasFile(file.path)) return false;
file.uuid = this.generateUuid();
- file.fileRef = this.generateUuid();
+ file.fileRef = this.generateUuid();
file.target = opt ? opt.target : undefined;
+ if (this.hasFile(file.path)) return false;
this.addToPbxBuildFileSection(file); // PBXBuildFile
this.addToPbxFileReferenceSection(file); // PBXFileReference
this.addToFrameworksPbxGroup(file); // PBXGroup
this.addToPbxFrameworksBuildPhase(file); // PBXFrameworksBuildPhase
-
- if(opt && opt.customFramework == true) {
- this.addToFrameworkSearchPaths(file);
+
+ if (opt && opt.customFramework == true) {
+ this.addToFrameworkSearchPaths(file);
}
return file;
}
-pbxProject.prototype.removeFramework = function (fpath, opt) {
+pbxProject.prototype.removeFramework = function(fpath, opt) {
var file = new pbxFile(fpath, opt);
file.target = opt ? opt.target : undefined;
@@ -217,15 +289,64 @@
this.removeFromPbxFileReferenceSection(file); // PBXFileReference
this.removeFromFrameworksPbxGroup(file); // PBXGroup
this.removeFromPbxFrameworksBuildPhase(file); // PBXFrameworksBuildPhase
-
- if(opt && opt.customFramework) {
- this.removeFromFrameworkSearchPaths(path.dirname(fpath));
+
+ if (opt && opt.customFramework) {
+ this.removeFromFrameworkSearchPaths(path.dirname(fpath));
}
return file;
}
-pbxProject.prototype.addStaticLibrary = function (path, opt) {
+
+pbxProject.prototype.addCopyfile = function(fpath, opt) {
+ var file = new pbxFile(fpath, opt);
+
+ // catch duplicates
+ if (this.hasFile(file.path)) {
+ file = this.hasFile(file.path);
+ }
+
+ file.fileRef = file.uuid = this.generateUuid();
+ file.target = opt ? opt.target : undefined;
+
+ this.addToPbxBuildFileSection(file); // PBXBuildFile
+ this.addToPbxFileReferenceSection(file); // PBXFileReference
+ this.addToPbxCopyfilesBuildPhase(file); // PBXCopyFilesBuildPhase
+
+ return file;
+}
+
+pbxProject.prototype.pbxCopyfilesBuildPhaseObj = function(target) {
+ return this.buildPhaseObject('PBXCopyFilesBuildPhase', 'Copy Files', target);
+}
+
+pbxProject.prototype.addToPbxCopyfilesBuildPhase = function(file) {
+ var sources = this.buildPhaseObject('PBXCopyFilesBuildPhase', 'Copy Files', file.target);
+ sources.files.push(pbxBuildPhaseObj(file));
+}
+
+pbxProject.prototype.removeCopyfile = function(fpath, opt) {
+ var file = new pbxFile(fpath, opt);
+ file.target = opt ? opt.target : undefined;
+
+ this.removeFromPbxBuildFileSection(file); // PBXBuildFile
+ this.removeFromPbxFileReferenceSection(file); // PBXFileReference
+ this.removeFromPbxCopyfilesBuildPhase(file); // PBXFrameworksBuildPhase
+
+ return file;
+}
+
+pbxProject.prototype.removeFromPbxCopyfilesBuildPhase = function(file) {
+ var sources = this.pbxCopyfilesBuildPhaseObj(file.target);
+ for (i in sources.files) {
+ if (sources.files[i].comment == longComment(file)) {
+ sources.files.splice(i, 1);
+ break;
+ }
+ }
+}
+
+pbxProject.prototype.addStaticLibrary = function(path, opt) {
opt = opt || {};
var file;
@@ -254,18 +375,18 @@
}
// helper addition functions
-pbxProject.prototype.addToPbxBuildFileSection = function (file) {
+pbxProject.prototype.addToPbxBuildFileSection = function(file) {
var commentKey = f("%s_comment", file.uuid);
this.pbxBuildFileSection()[file.uuid] = pbxBuildFileObj(file);
this.pbxBuildFileSection()[commentKey] = pbxBuildFileComment(file);
}
-pbxProject.prototype.removeFromPbxBuildFileSection = function (file) {
+pbxProject.prototype.removeFromPbxBuildFileSection = function(file) {
var uuid;
- for(uuid in this.pbxBuildFileSection()) {
- if(this.pbxBuildFileSection()[uuid].fileRef_comment == file.basename) {
+ for (uuid in this.pbxBuildFileSection()) {
+ if (this.pbxBuildFileSection()[uuid].fileRef_comment == file.basename) {
file.uuid = uuid;
delete this.pbxBuildFileSection()[uuid];
}
@@ -274,7 +395,7 @@
delete this.pbxBuildFileSection()[commentKey];
}
-pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceTree) {
+pbxProject.prototype.addPbxGroup = function(filePathsArray, name, path, sourceTree) {
var groups = this.hash.project.objects['PBXGroup'],
pbxGroupUuid = this.generateUuid(),
commentKey = f("%s_comment", pbxGroupUuid),
@@ -287,15 +408,15 @@
},
fileReferenceSection = this.pbxFileReferenceSection(),
filePathToReference = {};
-
+
for (var key in fileReferenceSection) {
// only look for comments
if (!COMMENT_KEY.test(key)) continue;
-
+
var fileReferenceKey = key.split(COMMENT_KEY)[0],
fileReference = fileReferenceSection[fileReferenceKey];
-
- filePathToReference[fileReference.path] = {fileRef: fileReferenceKey, basename: fileReferenceSection[key]};
+
+ filePathToReference[fileReference.path] = { fileRef: fileReferenceKey, basename: fileReferenceSection[key] };
}
for (var index = 0; index < filePathsArray.length; index++) {
@@ -308,7 +429,7 @@
pbxGroup.children.push(pbxGroupChild(filePathToReference[filePathQuoted]));
continue;
}
-
+
var file = new pbxFile(filePath);
file.uuid = this.generateUuid();
file.fileRef = this.generateUuid();
@@ -316,13 +437,13 @@
this.addToPbxBuildFileSection(file); // PBXBuildFile
pbxGroup.children.push(pbxGroupChild(file));
}
-
+
if (groups) {
groups[pbxGroupUuid] = pbxGroup;
groups[commentKey] = name;
}
-
- return {uuid: pbxGroupUuid, pbxGroup: pbxGroup};
+
+ return { uuid: pbxGroupUuid, pbxGroup: pbxGroup };
}
pbxProject.prototype.removePbxGroup = function (groupName) {
@@ -340,146 +461,175 @@
}
}
-pbxProject.prototype.addToPbxFileReferenceSection = function (file) {
+pbxProject.prototype.addToPbxProjectSection = function(target) {
+
+ var newTarget = {
+ value: target.uuid,
+ comment: pbxNativeTargetComment(target.pbxNativeTarget)
+ };
+
+ this.pbxProjectSection()[this.getFirstProject()['uuid']]['targets'].push(newTarget);
+}
+
+pbxProject.prototype.addToPbxNativeTargetSection = function(target) {
+ var commentKey = f("%s_comment", target.uuid);
+
+ this.pbxNativeTargetSection()[target.uuid] = target.pbxNativeTarget;
+ this.pbxNativeTargetSection()[commentKey] = target.pbxNativeTarget.name;
+}
+
+pbxProject.prototype.addToPbxFileReferenceSection = function(file) {
var commentKey = f("%s_comment", file.fileRef);
this.pbxFileReferenceSection()[file.fileRef] = pbxFileReferenceObj(file);
this.pbxFileReferenceSection()[commentKey] = pbxFileReferenceComment(file);
}
-pbxProject.prototype.removeFromPbxFileReferenceSection = function (file) {
+pbxProject.prototype.removeFromPbxFileReferenceSection = function(file) {
+
+ var i;
var refObj = pbxFileReferenceObj(file);
- var pbxFileReferenceSection = this.pbxFileReferenceSection();
- for (var i in pbxFileReferenceSection) {
- var pbxFileReferenceSectionName = quote(pbxFileReferenceSection[i].name);
- var pbxFileReferenceSectionPath = quote(pbxFileReferenceSection[i].path);
- var refObjName = quote(refObj.name);
- var refObjPath = quote(refObj.path);
- if (pbxFileReferenceSectionName == refObjName ||
- pbxFileReferenceSectionName == refObjPath ||
- pbxFileReferenceSectionPath == refObjPath ||
- pbxFileReferenceSectionPath == refObjName) {
+ for (i in this.pbxFileReferenceSection()) {
+ if (this.pbxFileReferenceSection()[i].name == refObj.name ||
+ ('"' + this.pbxFileReferenceSection()[i].name + '"') == refObj.name ||
+ this.pbxFileReferenceSection()[i].path == refObj.path ||
+ ('"' + this.pbxFileReferenceSection()[i].path + '"') == refObj.path) {
file.fileRef = file.uuid = i;
- delete pbxFileReferenceSection[i];
+ delete this.pbxFileReferenceSection()[i];
break;
}
}
-
- if (typeof file.fileRef !== 'undefined') {
- var commentKey = f("%s_comment", file.fileRef);
- delete pbxFileReferenceSection[commentKey];
+ var commentKey = f("%s_comment", file.fileRef);
+ if (this.pbxFileReferenceSection()[commentKey] != undefined) {
+ delete this.pbxFileReferenceSection()[commentKey];
}
return file;
}
-pbxProject.prototype.addToPluginsPbxGroup = function (file) {
+pbxProject.prototype.addToPluginsPbxGroup = function(file) {
var pluginsGroup = this.pbxGroupByName('Plugins');
pluginsGroup.children.push(pbxGroupChild(file));
}
-pbxProject.prototype.removeFromPluginsPbxGroup = function (file) {
+pbxProject.prototype.removeFromPluginsPbxGroup = function(file) {
var pluginsGroupChildren = this.pbxGroupByName('Plugins').children, i;
- for(i in pluginsGroupChildren) {
- if(pbxGroupChild(file).value == pluginsGroupChildren[i].value &&
- pbxGroupChild(file).comment == pluginsGroupChildren[i].comment) {
+ for (i in pluginsGroupChildren) {
+ if (pbxGroupChild(file).value == pluginsGroupChildren[i].value &&
+ pbxGroupChild(file).comment == pluginsGroupChildren[i].comment) {
pluginsGroupChildren.splice(i, 1);
break;
}
}
}
-pbxProject.prototype.addToResourcesPbxGroup = function (file) {
+pbxProject.prototype.addToResourcesPbxGroup = function(file) {
var pluginsGroup = this.pbxGroupByName('Resources');
pluginsGroup.children.push(pbxGroupChild(file));
}
-pbxProject.prototype.removeFromResourcesPbxGroup = function (file) {
- var groupChild = pbxGroupChild(file);
- var resourcesGroupChildren = this.pbxGroupByName('Resources').children;
- for (var i in resourcesGroupChildren) {
- var resourcesGroupChild = resourcesGroupChildren[i];
- if ((typeof groupChild.value === 'undefined' || groupChild.value == resourcesGroupChild.value) &&
- groupChild.comment == resourcesGroupChild.comment) {
- resourcesGroupChildren.splice(i, 1);
- break;
- }
- }
-}
-
-pbxProject.prototype.addToFrameworksPbxGroup = function (file) {
- var pluginsGroup = this.pbxGroupByName('Frameworks');
- pluginsGroup.children.push(pbxGroupChild(file));
-}
-
-pbxProject.prototype.removeFromFrameworksPbxGroup = function (file) {
- var pluginsGroupChildren = this.pbxGroupByName('Frameworks').children;
-
- for(i in pluginsGroupChildren) {
- if(pbxGroupChild(file).value == pluginsGroupChildren[i].value &&
- pbxGroupChild(file).comment == pluginsGroupChildren[i].comment) {
+pbxProject.prototype.removeFromResourcesPbxGroup = function(file) {
+ var pluginsGroupChildren = this.pbxGroupByName('Resources').children, i;
+ for (i in pluginsGroupChildren) {
+ if (pbxGroupChild(file).value == pluginsGroupChildren[i].value &&
+ pbxGroupChild(file).comment == pluginsGroupChildren[i].comment) {
pluginsGroupChildren.splice(i, 1);
break;
}
}
}
-pbxProject.prototype.addToPbxSourcesBuildPhase = function (file) {
+
+pbxProject.prototype.addToFrameworksPbxGroup = function(file) {
+ var pluginsGroup = this.pbxGroupByName('Frameworks');
+ pluginsGroup.children.push(pbxGroupChild(file));
+}
+
+pbxProject.prototype.removeFromFrameworksPbxGroup = function(file) {
+ var pluginsGroupChildren = this.pbxGroupByName('Frameworks').children;
+
+ for (i in pluginsGroupChildren) {
+ if (pbxGroupChild(file).value == pluginsGroupChildren[i].value &&
+ pbxGroupChild(file).comment == pluginsGroupChildren[i].comment) {
+ pluginsGroupChildren.splice(i, 1);
+ break;
+ }
+ }
+}
+
+
+pbxProject.prototype.addToProductsPbxGroup = function(file) {
+ var productsGroup = this.pbxGroupByName('Products');
+ productsGroup.children.push(pbxGroupChild(file));
+}
+
+pbxProject.prototype.removeFromProductsPbxGroup = function(file) {
+ var productsGroupChildren = this.pbxGroupByName('Products').children, i;
+ for (i in productsGroupChildren) {
+ if (pbxGroupChild(file).value == productsGroupChildren[i].value &&
+ pbxGroupChild(file).comment == productsGroupChildren[i].comment) {
+ productsGroupChildren.splice(i, 1);
+ break;
+ }
+ }
+}
+
+pbxProject.prototype.addToPbxSourcesBuildPhase = function(file) {
var sources = this.pbxSourcesBuildPhaseObj(file.target);
sources.files.push(pbxBuildPhaseObj(file));
}
-pbxProject.prototype.removeFromPbxSourcesBuildPhase = function (file) {
+pbxProject.prototype.removeFromPbxSourcesBuildPhase = function(file) {
var sources = this.pbxSourcesBuildPhaseObj(file.target), i;
- for(i in sources.files) {
- if(sources.files[i].comment == longComment(file)) {
+ for (i in sources.files) {
+ if (sources.files[i].comment == longComment(file)) {
sources.files.splice(i, 1);
- break;
+ break;
}
}
}
-pbxProject.prototype.addToPbxResourcesBuildPhase = function (file) {
+pbxProject.prototype.addToPbxResourcesBuildPhase = function(file) {
var sources = this.pbxResourcesBuildPhaseObj(file.target);
sources.files.push(pbxBuildPhaseObj(file));
}
-pbxProject.prototype.removeFromPbxResourcesBuildPhase = function (file) {
+pbxProject.prototype.removeFromPbxResourcesBuildPhase = function(file) {
var sources = this.pbxResourcesBuildPhaseObj(file.target), i;
- for(i in sources.files) {
- if(sources.files[i].comment == longComment(file)) {
+ for (i in sources.files) {
+ if (sources.files[i].comment == longComment(file)) {
sources.files.splice(i, 1);
break;
}
}
}
-pbxProject.prototype.addToPbxFrameworksBuildPhase = function (file) {
+pbxProject.prototype.addToPbxFrameworksBuildPhase = function(file) {
var sources = this.pbxFrameworksBuildPhaseObj(file.target);
sources.files.push(pbxBuildPhaseObj(file));
}
-pbxProject.prototype.removeFromPbxFrameworksBuildPhase = function (file) {
+pbxProject.prototype.removeFromPbxFrameworksBuildPhase = function(file) {
var sources = this.pbxFrameworksBuildPhaseObj(file.target);
- for(i in sources.files) {
- if(sources.files[i].comment == longComment(file)) {
+ for (i in sources.files) {
+ if (sources.files[i].comment == longComment(file)) {
sources.files.splice(i, 1);
break;
}
}
}
-pbxProject.prototype.addXCConfigurationList = function (configurationObjectsArray, defaultConfigurationName, comment) {
+pbxProject.prototype.addXCConfigurationList = function(configurationObjectsArray, defaultConfigurationName, comment) {
var pbxBuildConfigurationSection = this.pbxXCBuildConfigurationSection(),
- pbxXCConfigurationListSection = this.pbxXCConfigurationList(),
+ pbxXCConfigurationListSection = this.pbxXCConfigurationList(),
xcConfigurationListUuid = this.generateUuid(),
commentKey = f("%s_comment", xcConfigurationListUuid),
- xcConfigurationList = {
+ xcConfigurationList = {
isa: 'XCConfigurationList',
buildConfigurations: [],
defaultConfigurationIsVisible: 0,
- defaultConfigurationName: defaultConfigurationName
+ defaultConfigurationName: defaultConfigurationName
};
for (var index = 0; index < configurationObjectsArray.length; index++) {
@@ -489,32 +639,32 @@
pbxBuildConfigurationSection[configurationUuid] = configuration;
pbxBuildConfigurationSection[configurationCommentKey] = configuration.name;
- xcConfigurationList.buildConfigurations.push({value: configurationUuid, comment: configuration.name});
+ xcConfigurationList.buildConfigurations.push({ value: configurationUuid, comment: configuration.name });
}
-
+
if (pbxXCConfigurationListSection) {
pbxXCConfigurationListSection[xcConfigurationListUuid] = xcConfigurationList;
pbxXCConfigurationListSection[commentKey] = comment;
}
-
- return {uuid: xcConfigurationListUuid, xcConfigurationList: xcConfigurationList};
+
+ return { uuid: xcConfigurationListUuid, xcConfigurationList: xcConfigurationList };
}
-pbxProject.prototype.addTargetDependency = function (target, dependencyTargets) {
+pbxProject.prototype.addTargetDependency = function(target, dependencyTargets) {
if (!target)
return undefined;
- var nativeTargets = this.pbxNativeTarget();
+ var nativeTargets = this.pbxNativeTargetSection();
if (typeof nativeTargets[target] == "undefined")
throw new Error("Invalid target: " + target);
-
+
for (var index = 0; index < dependencyTargets.length; index++) {
var dependencyTarget = dependencyTargets[index];
if (typeof nativeTargets[dependencyTarget] == "undefined")
throw new Error("Invalid target: " + dependencyTarget);
- }
-
+ }
+
var pbxTargetDependency = 'PBXTargetDependency',
pbxContainerItemProxy = 'PBXContainerItemProxy',
pbxTargetDependencySection = this.hash.project.objects[pbxTargetDependency],
@@ -527,61 +677,84 @@
targetDependencyCommentKey = f("%s_comment", targetDependencyUuid),
itemProxyUuid = this.generateUuid(),
itemProxyCommentKey = f("%s_comment", itemProxyUuid),
- itemProxy = {
+ itemProxy = {
isa: pbxContainerItemProxy,
containerPortal: this.hash.project['rootObject'],
containerPortal_comment: this.hash.project['rootObject_comment'],
proxyType: 1,
remoteGlobalIDString: dependencyTargetUuid,
- remoteInfo: nativeTargets[dependencyTargetUuid].name
+ remoteInfo: nativeTargets[dependencyTargetUuid].name
},
targetDependency = {
isa: pbxTargetDependency,
- target: dependencyTargetUuid,
+ target: dependencyTargetUuid,
target_comment: nativeTargets[dependencyTargetCommentKey],
targetProxy: itemProxyUuid,
targetProxy_comment: pbxContainerItemProxy
};
-
+
if (pbxContainerItemProxySection && pbxTargetDependencySection) {
pbxContainerItemProxySection[itemProxyUuid] = itemProxy;
pbxContainerItemProxySection[itemProxyCommentKey] = pbxContainerItemProxy;
pbxTargetDependencySection[targetDependencyUuid] = targetDependency;
pbxTargetDependencySection[targetDependencyCommentKey] = pbxTargetDependency;
- nativeTargets[target].dependencies.push({value: targetDependencyUuid, comment: pbxTargetDependency})
+ nativeTargets[target].dependencies.push({ value: targetDependencyUuid, comment: pbxTargetDependency })
}
}
-
- return {uuid: target, target: nativeTargets[target]};
+
+ return { uuid: target, target: nativeTargets[target] };
}
-pbxProject.prototype.addBuildPhase = function (filePathsArray, isa, comment) {
- var section = this.hash.project.objects[isa],
+pbxProject.prototype.addBuildPhase = function(filePathsArray, buildPhaseType, comment, target, folderType, subfolderPath) {
+ var buildPhaseSection,
fileReferenceSection = this.pbxFileReferenceSection(),
buildFileSection = this.pbxBuildFileSection(),
buildPhaseUuid = this.generateUuid(),
+ buildPhaseTargetUuid = target || this.getFirstTarget().uuid,
commentKey = f("%s_comment", buildPhaseUuid),
buildPhase = {
- isa: isa,
+ isa: buildPhaseType,
buildActionMask: 2147483647,
files: [],
runOnlyForDeploymentPostprocessing: 0
},
filePathToBuildFile = {};
-
+
+ if (buildPhaseType === 'PBXCopyFilesBuildPhase') {
+ buildPhase = pbxCopyFilesBuildPhaseObj(buildPhase, folderType, subfolderPath, comment);
+ }
+
+ if (!this.hash.project.objects[buildPhaseType]) {
+ this.hash.project.objects[buildPhaseType] = new Object();
+ }
+
+ if (!this.hash.project.objects[buildPhaseType][buildPhaseUuid]) {
+ this.hash.project.objects[buildPhaseType][buildPhaseUuid] = buildPhase;
+ this.hash.project.objects[buildPhaseType][commentKey] = comment;
+ }
+
+ if (this.hash.project.objects['PBXNativeTarget'][buildPhaseTargetUuid]['buildPhases']) {
+ this.hash.project.objects['PBXNativeTarget'][buildPhaseTargetUuid]['buildPhases'].push({
+ value: buildPhaseUuid,
+ comment: comment
+ })
+
+ }
+
+
for (var key in buildFileSection) {
// only look for comments
if (!COMMENT_KEY.test(key)) continue;
-
+
var buildFileKey = key.split(COMMENT_KEY)[0],
buildFile = buildFileSection[buildFileKey];
- fileReference = fileReferenceSection[buildFile.fileRef];
+ fileReference = fileReferenceSection[buildFile.fileRef];
if (!fileReference) continue;
var pbxFileObj = new pbxFile(fileReference.path);
-
- filePathToBuildFile[fileReference.path] = {uuid: buildFileKey, basename: pbxFileObj.basename, group: pbxFileObj.group};
+
+ filePathToBuildFile[fileReference.path] = { uuid: buildFileKey, basename: pbxFileObj.basename, group: pbxFileObj.group };
}
for (var index = 0; index < filePathsArray.length; index++) {
@@ -596,55 +769,68 @@
buildPhase.files.push(pbxBuildPhaseObj(filePathToBuildFile[filePathQuoted]));
continue;
}
-
+
file.uuid = this.generateUuid();
file.fileRef = this.generateUuid();
this.addToPbxFileReferenceSection(file); // PBXFileReference
this.addToPbxBuildFileSection(file); // PBXBuildFile
buildPhase.files.push(pbxBuildPhaseObj(file));
}
-
- if (section) {
- section[buildPhaseUuid] = buildPhase;
- section[commentKey] = comment;
+
+ if (buildPhaseSection) {
+ buildPhaseSection[buildPhaseUuid] = buildPhase;
+ buildPhaseSection[commentKey] = comment;
}
-
- return {uuid: buildPhaseUuid, buildPhase: buildPhase};
+
+ return { uuid: buildPhaseUuid, buildPhase: buildPhase };
}
// helper access functions
-pbxProject.prototype.pbxProjectSection = function () {
+pbxProject.prototype.pbxProjectSection = function() {
return this.hash.project.objects['PBXProject'];
}
-pbxProject.prototype.pbxBuildFileSection = function () {
+pbxProject.prototype.pbxBuildFileSection = function() {
return this.hash.project.objects['PBXBuildFile'];
}
-pbxProject.prototype.pbxXCBuildConfigurationSection = function () {
+pbxProject.prototype.pbxXCBuildConfigurationSection = function() {
return this.hash.project.objects['XCBuildConfiguration'];
}
-pbxProject.prototype.pbxFileReferenceSection = function () {
+pbxProject.prototype.pbxFileReferenceSection = function() {
return this.hash.project.objects['PBXFileReference'];
}
-pbxProject.prototype.pbxNativeTarget = function () {
+pbxProject.prototype.pbxNativeTargetSection = function() {
return this.hash.project.objects['PBXNativeTarget'];
}
-pbxProject.prototype.pbxXCConfigurationList = function () {
+pbxProject.prototype.pbxXCConfigurationList = function() {
return this.hash.project.objects['XCConfigurationList'];
}
-pbxProject.prototype.pbxGroupByName = function (name) {
- return this.pbxItemByComment(name, 'PBXGroup');
+pbxProject.prototype.pbxGroupByName = function(name) {
+ var groups = this.hash.project.objects['PBXGroup'],
+ key, groupKey;
+
+ for (key in groups) {
+ // only look for comments
+ if (!COMMENT_KEY.test(key)) continue;
+
+ if (groups[key] == name) {
+ groupKey = key.split(COMMENT_KEY)[0];
+ return groups[groupKey];
+ }
+ }
+
+ return null;
}
-pbxProject.prototype.pbxTargetByName = function (name) {
+pbxProject.prototype.pbxTargetByName = function(name) {
return this.pbxItemByComment(name, 'PBXNativeTarget');
}
-pbxProject.prototype.pbxItemByComment = function (name, pbxSectionName) {
+pbxProject.prototype.pbxItemByComment = function(name, pbxSectionName) {
var section = this.hash.project.objects[pbxSectionName],
key, itemKey;
@@ -661,70 +847,107 @@
return null;
}
-pbxProject.prototype.pbxSourcesBuildPhaseObj = function (target) {
+pbxProject.prototype.pbxSourcesBuildPhaseObj = function(target) {
return this.buildPhaseObject('PBXSourcesBuildPhase', 'Sources', target);
}
-pbxProject.prototype.pbxResourcesBuildPhaseObj = function (target) {
- return this.buildPhaseObject('PBXResourcesBuildPhase', 'Resources',target);
+pbxProject.prototype.pbxResourcesBuildPhaseObj = function(target) {
+ return this.buildPhaseObject('PBXResourcesBuildPhase', 'Resources', target);
}
-pbxProject.prototype.pbxFrameworksBuildPhaseObj = function (target) {
- return this.buildPhaseObject('PBXFrameworksBuildPhase', 'Frameworks',target);
+pbxProject.prototype.pbxFrameworksBuildPhaseObj = function(target) {
+ return this.buildPhaseObject('PBXFrameworksBuildPhase', 'Frameworks', target);
}
// Find Build Phase from group/target
-pbxProject.prototype.buildPhase = function (group,target) {
+pbxProject.prototype.buildPhase = function(group, target) {
if (!target)
return undefined;
- var nativeTargets = this.pbxNativeTarget();
+ var nativeTargets = this.pbxNativeTargetSection();
if (typeof nativeTargets[target] == "undefined")
- throw new Error("Invalid target: "+target);
+ throw new Error("Invalid target: " + target);
- var nativeTarget= nativeTargets[target];
- var buildPhases = nativeTarget.buildPhases;
+ var nativeTarget = nativeTargets[target];
+ var buildPhases = nativeTarget.buildPhases;
for(var i in buildPhases)
{
var buildPhase = buildPhases[i];
if (buildPhase.comment==group)
- return buildPhase.value+"_comment";
- }
-}
+ return buildPhase.value + "_comment";
+ }
+ }
-pbxProject.prototype.buildPhaseObject = function (name, group,target) {
+pbxProject.prototype.buildPhaseObject = function(name, group, target) {
var section = this.hash.project.objects[name],
obj, sectionKey, key;
- var buildPhase = this.buildPhase(group,target);
+ var buildPhase = this.buildPhase(group, target);
for (key in section) {
// only look for comments
if (!COMMENT_KEY.test(key)) continue;
-
+
// select the proper buildPhase
if (buildPhase && buildPhase!=key)
continue;
if (section[key] == group) {
- sectionKey = key.split(COMMENT_KEY)[0];
+ sectionKey = key.split(COMMENT_KEY)[0];
return section[sectionKey];
}
- }
+ }
return null;
}
+pbxProject.prototype.addBuildProperty = function(prop, value, build_name) {
+ var configurations = nonComments(this.pbxXCBuildConfigurationSection()),
+ key, configuration;
-pbxProject.prototype.updateBuildProperty = function(prop, value) {
- var config = this.pbxXCBuildConfigurationSection();
- propReplace(config, prop, value);
+ for (key in configurations){
+ configuration = configurations[key];
+ if (!build_name || configuration.name === build_name){
+ configuration.buildSettings[prop] = value;
+ }
+ }
+}
+
+pbxProject.prototype.removeBuildProperty = function(prop, build_name) {
+ var configurations = nonComments(this.pbxXCBuildConfigurationSection()),
+ key, configuration;
+
+ for (key in configurations){
+ configuration = configurations[key];
+ if (configuration.buildSettings[prop] &&
+ !build_name || configuration.name === build_name){
+ delete configuration.buildSettings[prop];
+ }
+ }
+}
+
+/**
+ *
+ * @param prop {String}
+ * @param value {String|Array|Object|Number|Boolean}
+ * @param build {String} Release or Debug
+ */
+pbxProject.prototype.updateBuildProperty = function(prop, value, build) {
+ var configs = this.pbxXCBuildConfigurationSection();
+ for (var configName in configs) {
+ if (!COMMENT_KEY.test(configName)) {
+ var config = configs[configName];
+ if ( (build && config.name === build) || (!build) ) {
+ config.buildSettings[prop] = value;
+ }
+ }
+ }
}
pbxProject.prototype.updateProductName = function(name) {
this.updateBuildProperty('PRODUCT_NAME', '"' + name + '"');
}
-pbxProject.prototype.removeFromFrameworkSearchPaths = function (file) {
+pbxProject.prototype.removeFromFrameworkSearchPaths = function(file) {
var configurations = nonComments(this.pbxXCBuildConfigurationSection()),
INHERITED = '"$(inherited)"',
SEARCH_PATHS = 'FRAMEWORK_SEARCH_PATHS',
@@ -752,7 +975,7 @@
}
}
-pbxProject.prototype.addToFrameworkSearchPaths = function (file) {
+pbxProject.prototype.addToFrameworkSearchPaths = function(file) {
var configurations = nonComments(this.pbxXCBuildConfigurationSection()),
INHERITED = '"$(inherited)"',
config, buildSettings, searchPaths;
@@ -764,7 +987,7 @@
continue;
if (!buildSettings['FRAMEWORK_SEARCH_PATHS']
- || buildSettings['FRAMEWORK_SEARCH_PATHS'] === INHERITED) {
+ || buildSettings['FRAMEWORK_SEARCH_PATHS'] === INHERITED) {
buildSettings['FRAMEWORK_SEARCH_PATHS'] = [INHERITED];
}
@@ -772,7 +995,7 @@
}
}
-pbxProject.prototype.removeFromLibrarySearchPaths = function (file) {
+pbxProject.prototype.removeFromLibrarySearchPaths = function(file) {
var configurations = nonComments(this.pbxXCBuildConfigurationSection()),
INHERITED = '"$(inherited)"',
SEARCH_PATHS = 'LIBRARY_SEARCH_PATHS',
@@ -800,7 +1023,7 @@
}
}
-pbxProject.prototype.addToLibrarySearchPaths = function (file) {
+pbxProject.prototype.addToLibrarySearchPaths = function(file) {
var configurations = nonComments(this.pbxXCBuildConfigurationSection()),
INHERITED = '"$(inherited)"',
config, buildSettings, searchPaths;
@@ -812,7 +1035,7 @@
continue;
if (!buildSettings['LIBRARY_SEARCH_PATHS']
- || buildSettings['LIBRARY_SEARCH_PATHS'] === INHERITED) {
+ || buildSettings['LIBRARY_SEARCH_PATHS'] === INHERITED) {
buildSettings['LIBRARY_SEARCH_PATHS'] = [INHERITED];
}
@@ -824,7 +1047,7 @@
}
}
-pbxProject.prototype.removeFromHeaderSearchPaths = function (file) {
+pbxProject.prototype.removeFromHeaderSearchPaths = function(file) {
var configurations = nonComments(this.pbxXCBuildConfigurationSection()),
INHERITED = '"$(inherited)"',
SEARCH_PATHS = 'HEADER_SEARCH_PATHS',
@@ -849,7 +1072,7 @@
}
}
-pbxProject.prototype.addToHeaderSearchPaths = function (file) {
+pbxProject.prototype.addToHeaderSearchPaths = function(file) {
var configurations = nonComments(this.pbxXCBuildConfigurationSection()),
INHERITED = '"$(inherited)"',
config, buildSettings, searchPaths;
@@ -942,7 +1165,7 @@
}
// a JS getter. hmmm
-pbxProject.prototype.__defineGetter__("productName", function () {
+pbxProject.prototype.__defineGetter__("productName", function() {
var configurations = nonComments(this.pbxXCBuildConfigurationSection()),
config, productName;
@@ -956,19 +1179,125 @@
});
// check if file is present
-pbxProject.prototype.hasFile = function (filePath) {
+pbxProject.prototype.hasFile = function(filePath) {
var files = nonComments(this.pbxFileReferenceSection()),
file, id;
for (id in files) {
file = files[id];
if (file.path == filePath || file.path == ('"' + filePath + '"')) {
- return true;
+ return file;
}
}
return false;
}
+pbxProject.prototype.addTarget = function(name, type, subfolder) {
+
+ // Setup uuid and name of new target
+ var targetUuid = this.generateUuid(),
+ targetType = type,
+ targetSubfolder = subfolder || name,
+ targetName = name.trim();
+
+ // Check type against list of allowed target types
+ if (!targetName) {
+ throw new Error("Target name missing.");
+ }
+
+ // Check type against list of allowed target types
+ if (!targetType) {
+ throw new Error("Target type missing.");
+ }
+
+ // Check type against list of allowed target types
+ if (!producttypeForTargettype(targetType)) {
+ throw new Error("Target type invalid: " + targetType);
+ }
+
+ // Build Configuration: Create
+ var buildConfigurationsList = [
+ {
+ name: 'Debug',
+ isa: 'XCBuildConfiguration',
+ buildSettings: {
+ GCC_PREPROCESSOR_DEFINITIONS: ['"DEBUG=1"', '"$(inherited)"'],
+ INFOPLIST_FILE: '"' + path.join(targetSubfolder, targetSubfolder + '-Info.plist' + '"'),
+ LD_RUNPATH_SEARCH_PATHS: '"$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"',
+ PRODUCT_NAME: '"' + targetName + '"',
+ SKIP_INSTALL: 'YES'
+ }
+ },
+ {
+ name: 'Release',
+ isa: 'XCBuildConfiguration',
+ buildSettings: {
+ INFOPLIST_FILE: '"' + path.join(targetSubfolder, targetSubfolder + '-Info.plist' + '"'),
+ LD_RUNPATH_SEARCH_PATHS: '"$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"',
+ PRODUCT_NAME: '"' + targetName + '"',
+ SKIP_INSTALL: 'YES'
+ }
+ }
+ ];
+
+ // Build Configuration: Add
+ var buildConfigurations = this.addXCConfigurationList(buildConfigurationsList, 'Release', 'Build configuration list for PBXNativeTarget "' + targetName +'"');
+
+ // Product: Create
+ var productName = targetName,
+ productType = producttypeForTargettype(targetType),
+ productFileType = filetypeForProducttype(productType),
+ productFile = this.addProductFile(productName, { group: 'Copy Files', 'target': targetUuid, 'explicitFileType': productFileType}),
+ productFileName = productFile.basename;
+
+
+ // Product: Add to build file list
+ this.addToPbxBuildFileSection(productFile);
+
+ // Target: Create
+ var target = {
+ uuid: targetUuid,
+ pbxNativeTarget: {
+ isa: 'PBXNativeTarget',
+ name: '"' + targetName + '"',
+ productName: '"' + targetName + '"',
+ productReference: productFile.fileRef,
+ productType: '"' + producttypeForTargettype(targetType) + '"',
+ buildConfigurationList: buildConfigurations.uuid,
+ buildPhases: [],
+ buildRules: [],
+ dependencies: []
+ }
+ };
+
+ // Target: Add to PBXNativeTarget section
+ this.addToPbxNativeTargetSection(target)
+
+ // Product: Embed (only for "extension"-type targets)
+ if (targetType === 'app_extension') {
+
+ // Create CopyFiles phase in first target
+ this.addBuildPhase([], 'PBXCopyFilesBuildPhase', 'Copy Files', this.getFirstTarget().uuid, targetType)
+
+ // Add product to CopyFiles phase
+ this.addToPbxCopyfilesBuildPhase(productFile)
+
+ // this.addBuildPhaseToTarget(newPhase.buildPhase, this.getFirstTarget().uuid)
+
+ };
+
+ // Target: Add uuid to root project
+ this.addToPbxProjectSection(target);
+
+ // Target: Add dependency for this target to first (main) target
+ this.addTargetDependency(this.getFirstTarget().uuid, [target.uuid]);
+
+
+ // Return target on success
+ return target;
+
+};
+
// helper recursive prop search+replace
function propReplace(obj, prop, value) {
var o = {};
@@ -996,26 +1325,18 @@
}
function pbxFileReferenceObj(file) {
- var obj = Object.create(null);
+ var fileObject = {
+ isa: "PBXFileReference",
+ name: "\"" + file.basename + "\"",
+ path: "\"" + file.path.replace(/\\/g, '/') + "\"",
+ sourceTree: file.sourceTree,
+ fileEncoding: file.fileEncoding,
+ lastKnownFileType: file.lastKnownFileType,
+ explicitFileType: file.explicitFileType,
+ includeInIndex: file.includeInIndex
+ };
- obj.isa = 'PBXFileReference';
- obj.lastKnownFileType = file.lastType;
-
- obj.name = "\"" + file.basename + "\"";
- obj.path = "\"" + file.path.replace(/\\/g, '/') + "\"";
-
- obj.sourceTree = file.sourceTree;
-
- if (file.fileEncoding)
- obj.fileEncoding = file.fileEncoding;
-
- if (file.explicitFileType)
- obj.explicitFileType = file.explicitFileType;
-
- if ('includeInIndex' in file)
- obj.includeInIndex = file.includeInIndex;
-
- return obj;
+ return fileObject;
}
function pbxGroupChild(file) {
@@ -1036,12 +1357,52 @@
return obj;
}
+function pbxCopyFilesBuildPhaseObj(obj, folderType, subfolderPath, phaseName){
+
+ // Add additional properties for 'CopyFiles' build phase
+ var DESTINATION_BY_TARGETTYPE = {
+ application: 'wrapper',
+ app_extension: 'plugins',
+ bundle: 'wrapper',
+ command_line_tool: 'wrapper',
+ dynamic_library: 'products_directory',
+ framework: 'shared_frameworks',
+ static_library: 'products_directory',
+ unit_test_bundle: 'wrapper',
+ watch_app: 'wrapper',
+ watch_extension: 'plugins'
+ }
+ var SUBFOLDERSPEC_BY_DESTINATION = {
+ absolute_path: 0,
+ executables: 6,
+ frameworks: 10,
+ java_resources: 15,
+ plugins: 13,
+ products_directory: 16,
+ resources: 7,
+ shared_frameworks: 11,
+ shared_support: 12,
+ wrapper: 1,
+ xpc_services: 0
+ }
+
+ obj.name = '"' + phaseName + '"';
+ obj.dstPath = subfolderPath || '""';
+ obj.dstSubfolderSpec = SUBFOLDERSPEC_BY_DESTINATION[DESTINATION_BY_TARGETTYPE[folderType]];
+
+ return obj;
+}
+
function pbxBuildFileComment(file) {
return longComment(file);
}
function pbxFileReferenceComment(file) {
- return file.basename;
+ return file.basename || path.basename(file.path);
+}
+
+function pbxNativeTargetComment(target) {
+ return target.name;
}
function longComment(file) {
@@ -1107,8 +1468,241 @@
if (str) return str.replace(/^"(.*)"$/, "$1");
}
-function quote(str) {
- if (str) return '"' + unquote(str) + '"';
+
+function buildPhaseNameForIsa (isa) {
+
+ BUILDPHASENAME_BY_ISA = {
+ PBXCopyFilesBuildPhase: 'Copy Files',
+ PBXResourcesBuildPhase: 'Resources',
+ PBXSourcesBuildPhase: 'Sources',
+ PBXFrameworksBuildPhase: 'Frameworks'
+ }
+
+ return BUILDPHASENAME_BY_ISA[isa]
}
+function producttypeForTargettype (targetType) {
+
+ PRODUCTTYPE_BY_TARGETTYPE = {
+ application: 'com.apple.product-type.application',
+ app_extension: 'com.apple.product-type.app-extension',
+ bundle: 'com.apple.product-type.bundle',
+ command_line_tool: 'com.apple.product-type.tool',
+ dynamic_library: 'com.apple.product-type.library.dynamic',
+ framework: 'com.apple.product-type.framework',
+ static_library: 'com.apple.product-type.library.static',
+ unit_test_bundle: 'com.apple.product-type.bundle.unit-test',
+ watch_app: 'com.apple.product-type.application.watchapp',
+ watch_extension: 'com.apple.product-type.watchkit-extension'
+ };
+
+ return PRODUCTTYPE_BY_TARGETTYPE[targetType]
+}
+
+function filetypeForProducttype (productType) {
+
+ FILETYPE_BY_PRODUCTTYPE = {
+ 'com.apple.product-type.application': '"wrapper.application"',
+ 'com.apple.product-type.app-extension': '"wrapper.app-extension"',
+ 'com.apple.product-type.bundle': '"wrapper.plug-in"',
+ 'com.apple.product-type.tool': '"compiled.mach-o.dylib"',
+ 'com.apple.product-type.library.dynamic': '"compiled.mach-o.dylib"',
+ 'com.apple.product-type.framework': '"wrapper.framework"',
+ 'com.apple.product-type.library.static': '"archive.ar"',
+ 'com.apple.product-type.bundle.unit-test': '"wrapper.cfbundle"',
+ 'com.apple.product-type.application.watchapp': '"wrapper.application"',
+ 'com.apple.product-type.watchkit-extension': '"wrapper.app-extension"'
+ };
+
+ return FILETYPE_BY_PRODUCTTYPE[productType]
+}
+
+pbxProject.prototype.getFirstProject = function() {
+
+ // Get pbxProject container
+ var pbxProjectContainer = this.pbxProjectSection();
+
+ // Get first pbxProject UUID
+ var firstProjectUuid = Object.keys(pbxProjectContainer)[0];
+
+ // Get first pbxProject
+ var firstProject = pbxProjectContainer[firstProjectUuid];
+
+ return {
+ uuid: firstProjectUuid,
+ firstProject: firstProject
+ }
+}
+
+pbxProject.prototype.getFirstTarget = function() {
+
+ // Get first targets UUID
+ var firstTargetUuid = this.getFirstProject()['firstProject']['targets'][0].value;
+
+ // Get first pbxNativeTarget
+ var firstTarget = this.pbxNativeTargetSection()[firstTargetUuid];
+
+ return {
+ uuid: firstTargetUuid,
+ firstTarget: firstTarget
+ }
+}
+
+/*** NEW ***/
+
+pbxProject.prototype.addToPbxGroup = function (file, groupKey) {
+ var group = this.getPBXGroupByKey(groupKey);
+ if (group && group.children !== undefined) {
+ if (typeof file === 'string') {
+ //Group Key
+ var childGroup = {
+ value:file,
+ comment: this.getPBXGroupByKey(file).name
+ };
+
+ group.children.push(childGroup);
+ }
+ else {
+ //File Object
+ group.children.push(pbxGroupChild(file));
+ }
+ }
+}
+
+pbxProject.prototype.removeFromPbxGroup = function (file, groupKey) {
+ var group = this.getPBXGroupByKey(groupKey);
+ if (group) {
+ var groupChildren = group.children, i;
+ for(i in groupChildren) {
+ if(pbxGroupChild(file).value == groupChildren[i].value &&
+ pbxGroupChild(file).comment == groupChildren[i].comment) {
+ groupChildren.splice(i, 1);
+ break;
+ }
+ }
+ }
+}
+
+pbxProject.prototype.getPBXGroupByKey = function(key) {
+ return this.hash.project.objects['PBXGroup'][key];
+};
+
+pbxProject.prototype.findPBXGroupKey = function(criteria) {
+ var groups = this.hash.project.objects['PBXGroup'];
+ var target;
+
+ for (var key in groups) {
+ // only look for comments
+ if (COMMENT_KEY.test(key)) continue;
+
+ var group = groups[key];
+ if (criteria && criteria.path && criteria.name) {
+ if (criteria.path === group.path && criteria.name === group.name) {
+ target = key;
+ break
+ }
+ }
+ else if (criteria && criteria.path) {
+ if (criteria.path === group.path) {
+ target = key;
+ break
+ }
+ }
+ else if (criteria && criteria.name) {
+ if (criteria.name === group.name) {
+ target = key;
+ break
+ }
+ }
+ }
+
+ return target;
+}
+
+pbxProject.prototype.pbxCreateGroup = function(name, pathName) {
+
+ //Create object
+ var model = {
+ isa:"PBXGroup",
+ children: [],
+ name: name,
+ path: pathName,
+ sourceTree: '"<group>"'
+ };
+ var key = this.generateUuid();
+
+ //Create comment
+ var commendId = key + '_comment';
+
+ //add obj and commentObj to groups;
+ var groups = this.hash.project.objects['PBXGroup'];
+ groups[commendId] = name;
+ groups[key] = model;
+
+ return key;
+}
+
+
+pbxProject.prototype.getPBXObject = function(name) {
+ return this.hash.project.objects[name];
+}
+
+
+
+pbxProject.prototype.addFile = function (path, group, opt) {
+ var file = new pbxFile(path, opt);
+
+ // null is better for early errors
+ if (this.hasFile(file.path)) return null;
+
+ file.fileRef = this.generateUuid();
+
+ this.addToPbxFileReferenceSection(file); // PBXFileReference
+ this.addToPbxGroup(file, group); // PBXGroup
+
+ return file;
+}
+
+pbxProject.prototype.removeFile = function (path, group, opt) {
+ var file = new pbxFile(path, opt);
+
+ this.removeFromPbxFileReferenceSection(file); // PBXFileReference
+ this.removeFromPbxGroup(file, group); // PBXGroup
+
+ return file;
+}
+
+
+
+pbxProject.prototype.getBuildProperty = function(prop, build) {
+ var target;
+ var configs = this.pbxXCBuildConfigurationSection();
+ for (var configName in configs) {
+ if (!COMMENT_KEY.test(configName)) {
+ var config = configs[configName];
+ if ( (build && config.name === build) || (build === undefined) ) {
+ if (config.buildSettings[prop] !== undefined) {
+ target = config.buildSettings[prop];
+ }
+ }
+ }
+ }
+ return target;
+}
+
+pbxProject.prototype.getBuildConfigByName = function(name) {
+ var target = {};
+ var configs = this.pbxXCBuildConfigurationSection();
+ for (var configName in configs) {
+ if (!COMMENT_KEY.test(configName)) {
+ var config = configs[configName];
+ if (config.name === name) {
+ target[configName] = config;
+ }
+ }
+ }
+ return target;
+}
+
+
module.exports = pbxProject;
diff --git a/package.json b/package.json
index 2b27495..fe18e2b 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"author": "Andrew Lunny <alunny@gmail.com>",
"name": "xcode",
"description": "parser for xcodeproj/project.pbxproj files",
- "version": "0.8.0",
+ "version": "0.8.2",
"main":"index.js",
"repository": {
"url": "https://github.com/alunny/node-xcode.git"
diff --git a/test/addFramework.js b/test/addFramework.js
index d4a4bf4..6b36f4b 100644
--- a/test/addFramework.js
+++ b/test/addFramework.js
@@ -81,7 +81,7 @@
fileRefEntry = fileRefSection[newFile.fileRef];
test.equal(fileRefEntry.isa, 'PBXFileReference');
- test.equal(fileRefEntry.lastKnownFileType, '"compiled.mach-o.dylib"');
+ test.equal(fileRefEntry.lastKnownFileType, 'compiled.mach-o.dylib');
test.equal(fileRefEntry.name, '"libsqlite3.dylib"');
test.equal(fileRefEntry.path, '"usr/lib/libsqlite3.dylib"');
test.equal(fileRefEntry.sourceTree, 'SDKROOT');
diff --git a/test/addResourceFile.js b/test/addResourceFile.js
index 4caa22b..e464ecd 100644
--- a/test/addResourceFile.js
+++ b/test/addResourceFile.js
@@ -90,7 +90,7 @@
test.equal(fileRefEntry.isa, 'PBXFileReference');
test.equal(fileRefEntry.fileEncoding, undefined);
- test.equal(fileRefEntry.lastKnownFileType, '"wrapper.plug-in"');
+ test.equal(fileRefEntry.lastKnownFileType, 'wrapper.plug-in');
test.equal(fileRefEntry.name, '"assets.bundle"');
test.equal(fileRefEntry.path, '"Resources/assets.bundle"');
test.equal(fileRefEntry.sourceTree, '"<group>"');
@@ -151,7 +151,7 @@
test.equal(fileRefEntry.isa, 'PBXFileReference');
test.equal(fileRefEntry.fileEncoding, undefined);
- test.equal(fileRefEntry.lastKnownFileType, '"wrapper.plug-in"');
+ test.equal(fileRefEntry.lastKnownFileType, 'wrapper.plug-in');
test.equal(fileRefEntry.name, '"assets.bundle"');
test.equal(fileRefEntry.path, '"Plugins/assets.bundle"');
test.equal(fileRefEntry.sourceTree, '"<group>"');
diff --git a/test/addTarget.js b/test/addTarget.js
new file mode 100644
index 0000000..265bb0d
--- /dev/null
+++ b/test/addTarget.js
@@ -0,0 +1,89 @@
+var fullProject = require('./fixtures/full-project')
+ fullProjectStr = JSON.stringify(fullProject),
+ pbx = require('../lib/pbxProject'),
+ proj = new pbx('.');
+
+function cleanHash() {
+ return JSON.parse(fullProjectStr);
+}
+
+var TARGET_NAME = 'TestExtension',
+ TARGET_TYPE = 'app_extension',
+ TARGET_SUBFOLDER_NAME = 'TestExtensionFiles';
+
+exports.setUp = function (callback) {
+ proj.hash = cleanHash();
+ callback();
+}
+
+exports.addTarget = {
+ 'should throw when target name is missing': function (test) {
+ test.throws(function() {
+ proj.addTarget(null, TARGET_TYPE);
+ });
+
+ test.done();
+ },
+ 'should throw when target type missing': function (test) {
+ test.throws(function() {
+ proj.addTarget(TARGET_NAME, null);
+ });
+
+ test.done();
+ },
+ 'should create a new target': function (test) {
+ var target = proj.addTarget(TARGET_NAME, TARGET_TYPE, TARGET_SUBFOLDER_NAME);
+
+ test.ok(typeof target == 'object');
+ test.ok(target.uuid);
+ test.ok(target.pbxNativeTarget);
+ test.ok(target.pbxNativeTarget.isa);
+ test.ok(target.pbxNativeTarget.name);
+ test.ok(target.pbxNativeTarget.productName);
+ test.ok(target.pbxNativeTarget.productReference);
+ test.ok(target.pbxNativeTarget.productType);
+ test.ok(target.pbxNativeTarget.buildConfigurationList);
+ test.ok(target.pbxNativeTarget.buildPhases);
+ test.ok(target.pbxNativeTarget.buildRules);
+ test.ok(target.pbxNativeTarget.dependencies);
+
+ test.done();
+ },
+ 'should create a new target and add source, framework, resource and header files and the corresponding build phases': function (test) {
+ var target = proj.addTarget(TARGET_NAME, TARGET_TYPE, TARGET_SUBFOLDER_NAME),
+ options = { 'target' : target.uuid };
+
+ var sourceFile = proj.addSourceFile('Plugins/file.m', options),
+ sourcePhase = proj.addBuildPhase([], 'PBXSourcesBuildPhase', 'Sources', target.uuid),
+ resourceFile = proj.addResourceFile('assets.bundle', options),
+ resourcePhase = proj.addBuildPhase([], 'PBXResourcesBuildPhase', 'Resources', target.uuid),
+ frameworkFile = proj.addFramework('libsqlite3.dylib', options);
+ frameworkPhase = proj.addBuildPhase([], 'PBXFrameworkBuildPhase', 'Frameworks', target.uuid),
+ headerFile = proj.addHeaderFile('file.h', options);
+
+ test.ok(sourcePhase);
+ test.ok(resourcePhase);
+ test.ok(frameworkPhase);
+
+ test.equal(sourceFile.constructor, pbxFile);
+ test.equal(resourceFile.constructor, pbxFile);
+ test.equal(frameworkFile.constructor, pbxFile);
+ test.equal(headerFile.constructor, pbxFile);
+
+ test.ok(typeof target == 'object');
+ test.ok(target.uuid);
+ test.ok(target.pbxNativeTarget);
+ test.ok(target.pbxNativeTarget.isa);
+ test.ok(target.pbxNativeTarget.name);
+ test.ok(target.pbxNativeTarget.productName);
+ test.ok(target.pbxNativeTarget.productReference);
+ test.ok(target.pbxNativeTarget.productType);
+ test.ok(target.pbxNativeTarget.buildConfigurationList);
+ test.ok(target.pbxNativeTarget.buildPhases);
+ test.ok(target.pbxNativeTarget.buildRules);
+ test.ok(target.pbxNativeTarget.dependencies);
+
+ test.done();
+
+ }
+}
diff --git a/test/addTargetDependency.js b/test/addTargetDependency.js
index d20c790..2ed6983 100644
--- a/test/addTargetDependency.js
+++ b/test/addTargetDependency.js
@@ -40,7 +40,7 @@
test.done();
},
'should add targetDependencies to target': function (test) {
- var targetInPbxProj = proj.pbxNativeTarget()['1D6058900D05DD3D006BFB55'];
+ var targetInPbxProj = proj.pbxNativeTargetSection()['1D6058900D05DD3D006BFB55'];
test.deepEqual(targetInPbxProj.dependencies, []);
var target = proj.addTargetDependency('1D6058900D05DD3D006BFB55', ['1D6058900D05DD3D006BFB54', '1D6058900D05DD3D006BFB55']).target;
diff --git a/test/group.js b/test/group.js
new file mode 100644
index 0000000..8523b83
--- /dev/null
+++ b/test/group.js
@@ -0,0 +1,320 @@
+var pbx = require('../lib/pbxProject'),
+ project,
+ projectHash;
+
+var findChildInGroup = function(obj, target) {
+ var found = false;
+
+ for (var i = 0, j = obj.children.length; i < j; i++) {
+ if (obj.children[i].value === target) {
+ found = true;
+ break;
+ }
+ }
+
+ return found;
+}
+
+var findFileByUUID = function(obj, target) {
+ var found = false;
+
+ for (var k = 0, l = obj.files.length; k < l; k++) {
+ if (obj.files[k].value === target) {
+ found = true;
+ break;
+ }
+ }
+
+ return found;
+}
+
+var findByFileRef = function(obj, target) {
+ var found = false;
+
+ for (var property in obj) {
+ if (!/comment/.test(property)) {
+ if (obj[property].fileRef === target) {
+ found = true;
+ break;
+ }
+ }
+ }
+ return found;
+}
+
+var findByName = function(obj, target) {
+ var found = false;
+ for (var property in obj) {
+ if (!/comment/.test(property)) {
+ var value = obj[property];
+ if (value.name === target) {
+ found = true;
+ }
+ }
+ }
+ return found;
+}
+
+exports.setUp = function(callback) {
+ project = new pbx('test/parser/projects/group.pbxproj');
+ projectHash = project.parseSync();
+ callback();
+}
+
+exports.getGroupByKey = {
+ 'should return PBXGroup for Classes': function(test) {
+ var groupKey = project.findPBXGroupKey({name: 'Classes'});
+ var group = project.getPBXGroupByKey(groupKey);
+ test.ok(group.name === 'Classes');
+ test.done();
+ },
+ 'should return PBXGroup for Plugins': function(test) {
+ var groupKey = project.findPBXGroupKey({name: 'Plugins'});
+ var group = project.getPBXGroupByKey(groupKey);
+ test.ok(group.name === 'Plugins');
+ test.done();
+ }
+}
+
+exports.createGroup = {
+ 'should create a new Test Group': function(test) {
+ var found = false;
+ var groups = project.getPBXObject('PBXGroup');
+
+ var found = findByName(groups, 'Test');
+ test.ok(found === false);
+
+
+ var group = project.findPBXGroupKey({name:'Test'});
+ test.ok(group === undefined);
+
+ project.pbxCreateGroup('Test', 'Test');
+
+ groups = project.getPBXObject('PBXGroup');
+ found = findByName(groups, 'Test');
+ test.ok(found === true);
+
+ group = project.findPBXGroupKey({name:'Test'});
+ test.ok(typeof group === 'string');
+ test.done();
+ }
+}
+
+exports.findGroupKey = {
+ 'should return a valid group key':function(test) {
+ var keyByName = project.findPBXGroupKey({ name: 'Classes'});
+ var keyByPath = project.findPBXGroupKey({ path: 'icons'});
+ var keyByPathName = project.findPBXGroupKey({ path: '"HelloCordova/Plugins"', name: 'Plugins'});
+ var nonExistingKey = project.findPBXGroupKey({ name: 'Foo'});
+
+ test.ok(keyByName === '080E96DDFE201D6D7F000001');
+ test.ok(keyByPath === '308D052D1370CCF300D202BF');
+ test.ok(keyByPathName === '307C750510C5A3420062BCA9');
+ test.ok(nonExistingKey === undefined);
+
+ test.done();
+ }
+}
+
+exports.addGroupToGroup = {
+ 'should create a new test group then add group to Classes group': function(test) {
+ var testKey = project.pbxCreateGroup('Test', 'Test');
+ var classesKey = project.findPBXGroupKey({name: 'Classes'});
+ project.addToPbxGroup(testKey, classesKey);
+
+ var classesGroup = project.getPBXGroupByKey(classesKey);
+ var foundTestGroup = false;
+ for (var i = 0, j = classesGroup.children.length; i < j; i++) {
+ var child = classesGroup.children[i];
+ if (child.value === testKey && child.comment === 'Test') {
+ foundTestGroup = true;
+ }
+ }
+
+ test.ok(foundTestGroup);
+
+ test.done();
+ }
+}
+
+exports.addSourceFileToGroup = {
+ 'should create group + add source file' : function(test) {
+ var testKey = project.pbxCreateGroup('Test', 'Test');
+ var file = project.addSourceFile('Notifications.m', {}, testKey);
+
+ var foundInGroup = findChildInGroup(project.getPBXGroupByKey(testKey),file.fileRef );
+ test.ok(foundInGroup);
+
+ var foundInBuildFileSection = findByFileRef(project.pbxBuildFileSection(), file.fileRef);
+ test.ok(foundInBuildFileSection);
+
+ var foundInBuildPhase = findFileByUUID(project.pbxSourcesBuildPhaseObj(), file.uuid);
+ test.ok(foundInBuildPhase);
+
+ test.done();
+ }
+}
+
+exports.removeSourceFileFromGroup = {
+ 'should create group + add source file then remove source file' : function(test) {
+ var testKey = project.pbxCreateGroup('Test', 'Test');
+ var file = project.addSourceFile('Notifications.m', {}, testKey);
+
+ var foundInGroup = findChildInGroup(project.getPBXGroupByKey(testKey),file.fileRef );
+ test.ok(foundInGroup);
+
+ var foundInBuildFileSection = findByFileRef(project.pbxBuildFileSection(), file.fileRef);
+ test.ok(foundInBuildFileSection);
+
+ var foundInBuildPhase = findFileByUUID(project.pbxSourcesBuildPhaseObj(), file.uuid);
+ test.ok(foundInBuildPhase);
+
+ project.removeSourceFile('Notifications.m', {}, testKey);
+
+ var foundInGroup = findChildInGroup(project.getPBXGroupByKey(testKey),file.fileRef );
+ test.ok(!foundInGroup);
+
+ var foundInBuildFileSection = findByFileRef(project.pbxBuildFileSection(), file.fileRef);
+ test.ok(!foundInBuildFileSection);
+
+ var foundInBuildPhase = findFileByUUID(project.pbxSourcesBuildPhaseObj(), file.uuid);
+ test.ok(!foundInBuildPhase);
+
+ test.done();
+ }
+}
+
+exports.addHeaderFileToGroup = {
+ 'should create group + add source file' : function(test) {
+ var testKey = project.pbxCreateGroup('Test', 'Test');
+ var file = project.addHeaderFile('Notifications.h', {}, testKey);
+
+ var foundInGroup = findChildInGroup(project.getPBXGroupByKey(testKey),file.fileRef );
+ test.ok(foundInGroup);
+
+ test.done();
+ }
+}
+
+exports.removeHeaderFileFromGroup = {
+ 'should create group + add source file then remove source file' : function(test) {
+ var testKey = project.pbxCreateGroup('Test', 'Test');
+ var file = project.addHeaderFile('Notifications.h', {}, testKey);
+
+ var foundInGroup = findChildInGroup(project.getPBXGroupByKey(testKey),file.fileRef );
+ test.ok(foundInGroup);
+
+ project.removeHeaderFile('Notifications.h', {}, testKey);
+
+ var foundInGroup = findChildInGroup(project.getPBXGroupByKey(testKey),file.fileRef );
+ test.ok(!foundInGroup);
+
+ test.done();
+ }
+}
+
+exports.retrieveBuildPropertyForBuild = {
+ 'should retrieve valid build property ':function(test) {
+ var releaseTargetedDeviceFamily = project.getBuildProperty('TARGETED_DEVICE_FAMILY', 'Release');
+ var debugTargetedDeviceFamily = project.getBuildProperty('TARGETED_DEVICE_FAMILY', 'Debug');
+ var nonExistingProperty = project.getBuildProperty('FOO', 'Debug');
+ var nonExistingBuild = project.getBuildProperty('TARGETED_DEVICE_FAMILY', 'Foo');
+
+ test.equal(releaseTargetedDeviceFamily, '"1,2"');
+ test.equal(debugTargetedDeviceFamily,'"1"');
+ test.equal(nonExistingProperty, undefined);
+ test.equal(nonExistingBuild, undefined);
+
+ test.done();
+ }
+}
+
+exports.retrieveBuildConfigByName = {
+ 'should retrieve valid build config':function(test) {
+ var releaseBuildConfig = project.getBuildConfigByName('Release');
+ for (var property in releaseBuildConfig) {
+ var value = releaseBuildConfig[property];
+ test.ok(value.name === 'Release');
+ }
+
+ var debugBuildConfig = project.getBuildConfigByName('Debug');
+ for (var property in debugBuildConfig) {
+ var value = debugBuildConfig[property];
+ test.ok(value.name === 'Debug');
+ }
+
+ var nonExistingBuildConfig = project.getBuildConfigByName('Foo');
+ test.deepEqual(nonExistingBuildConfig, {});
+
+ test.done();
+ }
+}
+
+/* This proves the issue in 0.6.7
+exports.validatePropReplaceException = {
+ 'should throw TypeError for updateBuildProperty VALID_ARCHS when none existed' : function(test) {
+ test.throws(
+ function() {
+ project.updateBuildProperty('VALID_ARCHS', '"armv7 armv7s');
+ },
+ TypeError,
+ "Object object has no method 'hasOwnProperty'"
+ );
+ test.done();
+ }
+}
+*/
+
+exports.validatePropReplaceFix = {
+ 'should create build configuration for VALID_ARCHS when none existed' : function(test) {
+ project.updateBuildProperty('VALID_ARCHS', '"armv7 armv7s"', 'Debug');
+ test.done();
+ }
+}
+
+exports.validateHasFile = {
+ 'should return true for has file MainViewController.m': function(test) {
+ var result = project.hasFile('MainViewController.m');
+ test.ok(result.path == "MainViewController.m");
+ test.done();
+ }
+}
+
+exports.testWritingPBXProject = {
+
+ 'should successfully write to PBXProject TargetAttributes': function(test) {
+ var pbxProjectObj = project.getPBXObject('PBXProject');
+ var pbxProject;
+ for (var property in pbxProjectObj) {
+ if (!/comment/.test(property)) {
+ pbxProject = pbxProjectObj[property];
+ }
+ }
+
+ var target;
+ var projectTargets = pbxProject.targets;
+ for (var i = 0, j = pbxProject.targets.length; i < j; i++ ) {
+ target = pbxProject.targets[i].value;
+ }
+
+ pbxProject.attributes.TargetAttributes = {};
+ pbxProject.attributes.TargetAttributes[target] = {
+ DevelopmentTeam: 'N6X4RJZZ5D',
+ SystemCapabilities: {
+ "com.apple.BackgroundModes": {
+ enabled : 0
+ },
+ "com.apple.DataProtection" : {
+ enabled : 0
+ },
+ "com.apple.Keychain" : {
+ enabled: 1
+ }
+ }
+ };
+
+ var output = project.writeSync();
+
+ test.done();
+ }
+}
\ No newline at end of file
diff --git a/test/parser/projects/group.pbxproj b/test/parser/projects/group.pbxproj
new file mode 100644
index 0000000..700242c
--- /dev/null
+++ b/test/parser/projects/group.pbxproj
@@ -0,0 +1,575 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; };
+ 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
+ 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; };
+ 301BF552109A68D80062928A /* libCordova.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF535109A57CC0062928A /* libCordova.a */; };
+ 302D95F114D2391D003F00A1 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 302D95EF14D2391D003F00A1 /* MainViewController.m */; };
+ 302D95F214D2391D003F00A1 /* MainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 302D95F014D2391D003F00A1 /* MainViewController.xib */; };
+ 305D5FD1115AB8F900A74A75 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */; };
+ 3088BBBD154F3926009F9C59 /* Default-Landscape@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBB7154F3926009F9C59 /* Default-Landscape@2x~ipad.png */; };
+ 3088BBBE154F3926009F9C59 /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBB8154F3926009F9C59 /* Default-Landscape~ipad.png */; };
+ 3088BBBF154F3926009F9C59 /* Default-Portrait@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBB9154F3926009F9C59 /* Default-Portrait@2x~ipad.png */; };
+ 3088BBC0154F3926009F9C59 /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBBA154F3926009F9C59 /* Default-Portrait~ipad.png */; };
+ 3088BBC1154F3926009F9C59 /* Default@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBBB154F3926009F9C59 /* Default@2x~iphone.png */; };
+ 3088BBC2154F3926009F9C59 /* Default~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBBC154F3926009F9C59 /* Default~iphone.png */; };
+ 308D05371370CCF300D202BF /* icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D052E1370CCF300D202BF /* icon-72.png */; };
+ 308D05381370CCF300D202BF /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D052F1370CCF300D202BF /* icon.png */; };
+ 308D05391370CCF300D202BF /* icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D05301370CCF300D202BF /* icon@2x.png */; };
+ 30B4F30019D5E07200D9F7D8 /* Default-667h.png in Resources */ = {isa = PBXBuildFile; fileRef = 30B4F2FD19D5E07200D9F7D8 /* Default-667h.png */; };
+ 30B4F30119D5E07200D9F7D8 /* Default-736h.png in Resources */ = {isa = PBXBuildFile; fileRef = 30B4F2FE19D5E07200D9F7D8 /* Default-736h.png */; };
+ 30B4F30219D5E07200D9F7D8 /* Default-Landscape-736h.png in Resources */ = {isa = PBXBuildFile; fileRef = 30B4F2FF19D5E07200D9F7D8 /* Default-Landscape-736h.png */; };
+ 30C1856619D5FC0A00212699 /* icon-60@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 30C1856519D5FC0A00212699 /* icon-60@3x.png */; };
+ 30FC414916E50CA1004E6F35 /* icon-72@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 30FC414816E50CA1004E6F35 /* icon-72@2x.png */; };
+ 5B1594DD16A7569C00FEF299 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */; };
+ 7E7966DE1810823500FA85AD /* icon-40.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D41810823500FA85AD /* icon-40.png */; };
+ 7E7966DF1810823500FA85AD /* icon-40@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D51810823500FA85AD /* icon-40@2x.png */; };
+ 7E7966E01810823500FA85AD /* icon-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D61810823500FA85AD /* icon-50.png */; };
+ 7E7966E11810823500FA85AD /* icon-50@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D71810823500FA85AD /* icon-50@2x.png */; };
+ 7E7966E21810823500FA85AD /* icon-60.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D81810823500FA85AD /* icon-60.png */; };
+ 7E7966E31810823500FA85AD /* icon-60@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D91810823500FA85AD /* icon-60@2x.png */; };
+ 7E7966E41810823500FA85AD /* icon-76.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DA1810823500FA85AD /* icon-76.png */; };
+ 7E7966E51810823500FA85AD /* icon-76@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DB1810823500FA85AD /* icon-76@2x.png */; };
+ 7E7966E61810823500FA85AD /* icon-small.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DC1810823500FA85AD /* icon-small.png */; };
+ 7E7966E71810823500FA85AD /* icon-small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DD1810823500FA85AD /* icon-small@2x.png */; };
+ D4A0D8761607E02300AEF8BB /* Default-568h@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 301BF534109A57CC0062928A /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = D2AAC07E0554694100DB518D;
+ remoteInfo = CordovaLib;
+ };
+ 301BF550109A68C00062928A /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = D2AAC07D0554694100DB518D;
+ remoteInfo = CordovaLib;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+ 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
+ 1D6058910D05DD3D006BFB54 /* HelloCordova.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "HelloCordova.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 1F766FDD13BBADB100FB74C0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = Localizable.strings; sourceTree = "<group>"; };
+ 1F766FE013BBADB100FB74C0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = Localizable.strings; sourceTree = "<group>"; };
+ 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CordovaLib.xcodeproj; path = "CordovaLib/CordovaLib.xcodeproj"; sourceTree = "<group>"; };
+ 301BF56E109A69640062928A /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; path = www; sourceTree = SOURCE_ROOT; };
+ 302D95EE14D2391D003F00A1 /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = "<group>"; };
+ 302D95EF14D2391D003F00A1 /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = "<group>"; };
+ 302D95F014D2391D003F00A1 /* MainViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainViewController.xib; sourceTree = "<group>"; };
+ 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
+ 3088BBB7154F3926009F9C59 /* Default-Landscape@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape@2x~ipad.png"; sourceTree = "<group>"; };
+ 3088BBB8154F3926009F9C59 /* Default-Landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape~ipad.png"; sourceTree = "<group>"; };
+ 3088BBB9154F3926009F9C59 /* Default-Portrait@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait@2x~ipad.png"; sourceTree = "<group>"; };
+ 3088BBBA154F3926009F9C59 /* Default-Portrait~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait~ipad.png"; sourceTree = "<group>"; };
+ 3088BBBB154F3926009F9C59 /* Default@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x~iphone.png"; sourceTree = "<group>"; };
+ 3088BBBC154F3926009F9C59 /* Default~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default~iphone.png"; sourceTree = "<group>"; };
+ 308D052E1370CCF300D202BF /* icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-72.png"; sourceTree = "<group>"; };
+ 308D052F1370CCF300D202BF /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = "<group>"; };
+ 308D05301370CCF300D202BF /* icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon@2x.png"; sourceTree = "<group>"; };
+ 30B4F2FD19D5E07200D9F7D8 /* Default-667h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-667h.png"; sourceTree = "<group>"; };
+ 30B4F2FE19D5E07200D9F7D8 /* Default-736h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h.png"; sourceTree = "<group>"; };
+ 30B4F2FF19D5E07200D9F7D8 /* Default-Landscape-736h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape-736h.png"; sourceTree = "<group>"; };
+ 30C1856519D5FC0A00212699 /* icon-60@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-60@3x.png"; sourceTree = "<group>"; };
+ 30FC414816E50CA1004E6F35 /* icon-72@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-72@2x.png"; sourceTree = "<group>"; };
+ 32CA4F630368D1EE00C91783 /* HelloCordova-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HelloCordova-Prefix.pch"; sourceTree = "<group>"; };
+ 5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; };
+ 7E7966D41810823500FA85AD /* icon-40.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-40.png"; sourceTree = "<group>"; };
+ 7E7966D51810823500FA85AD /* icon-40@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-40@2x.png"; sourceTree = "<group>"; };
+ 7E7966D61810823500FA85AD /* icon-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-50.png"; sourceTree = "<group>"; };
+ 7E7966D71810823500FA85AD /* icon-50@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-50@2x.png"; sourceTree = "<group>"; };
+ 7E7966D81810823500FA85AD /* icon-60.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-60.png"; sourceTree = "<group>"; };
+ 7E7966D91810823500FA85AD /* icon-60@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-60@2x.png"; sourceTree = "<group>"; };
+ 7E7966DA1810823500FA85AD /* icon-76.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-76.png"; sourceTree = "<group>"; };
+ 7E7966DB1810823500FA85AD /* icon-76@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-76@2x.png"; sourceTree = "<group>"; };
+ 7E7966DC1810823500FA85AD /* icon-small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small.png"; sourceTree = "<group>"; };
+ 7E7966DD1810823500FA85AD /* icon-small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small@2x.png"; sourceTree = "<group>"; };
+ 8D1107310486CEB800E47090 /* HelloCordova-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "HelloCordova-Info.plist"; path = "../HelloCordova-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
+ D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x~iphone.png"; sourceTree = "<group>"; };
+ EB87FDF21871DA7A0020F90C /* merges */ = {isa = PBXFileReference; lastKnownFileType = folder; name = merges; path = ../../merges; sourceTree = "<group>"; };
+ EB87FDF31871DA8E0020F90C /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; name = www; path = ../../www; sourceTree = "<group>"; };
+ EB87FDF41871DAF40020F90C /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = config.xml; path = ../../config.xml; sourceTree = "<group>"; };
+ F840E1F0165FE0F500CFE078 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = config.xml; path = "HelloCordova/config.xml"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 1D60588F0D05DD3D006BFB54 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5B1594DD16A7569C00FEF299 /* AssetsLibrary.framework in Frameworks */,
+ 301BF552109A68D80062928A /* libCordova.a in Frameworks */,
+ 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */,
+ 305D5FD1115AB8F900A74A75 /* MobileCoreServices.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 080E96DDFE201D6D7F000001 /* Classes */ = {
+ isa = PBXGroup;
+ children = (
+ 302D95EE14D2391D003F00A1 /* MainViewController.h */,
+ 302D95EF14D2391D003F00A1 /* MainViewController.m */,
+ 302D95F014D2391D003F00A1 /* MainViewController.xib */,
+ 1D3623240D0F684500981E51 /* AppDelegate.h */,
+ 1D3623250D0F684500981E51 /* AppDelegate.m */,
+ );
+ name = Classes;
+ path = "HelloCordova/Classes";
+ sourceTree = SOURCE_ROOT;
+ };
+ 19C28FACFE9D520D11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 1D6058910D05DD3D006BFB54 /* HelloCordova.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
+ isa = PBXGroup;
+ children = (
+ EB87FDF41871DAF40020F90C /* config.xml */,
+ EB87FDF31871DA8E0020F90C /* www */,
+ EB87FDF21871DA7A0020F90C /* merges */,
+ EB87FDF11871DA420020F90C /* Staging */,
+ 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */,
+ 080E96DDFE201D6D7F000001 /* Classes */,
+ 307C750510C5A3420062BCA9 /* Plugins */,
+ 29B97315FDCFA39411CA2CEA /* Other Sources */,
+ 29B97317FDCFA39411CA2CEA /* Resources */,
+ 29B97323FDCFA39411CA2CEA /* Frameworks */,
+ 19C28FACFE9D520D11CA2CBB /* Products */,
+ );
+ name = CustomTemplate;
+ sourceTree = "<group>";
+ };
+ 29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 32CA4F630368D1EE00C91783 /* HelloCordova-Prefix.pch */,
+ 29B97316FDCFA39411CA2CEA /* main.m */,
+ );
+ name = "Other Sources";
+ path = "HelloCordova";
+ sourceTree = "<group>";
+ };
+ 29B97317FDCFA39411CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 308D052D1370CCF300D202BF /* icons */,
+ 308D05311370CCF300D202BF /* splash */,
+ 8D1107310486CEB800E47090 /* HelloCordova-Info.plist */,
+ );
+ name = Resources;
+ path = "HelloCordova/Resources";
+ sourceTree = "<group>";
+ };
+ 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */,
+ 288765FC0DF74451002DB57D /* CoreGraphics.framework */,
+ 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ 301BF52E109A57CC0062928A /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 301BF535109A57CC0062928A /* libCordova.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 307C750510C5A3420062BCA9 /* Plugins */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = Plugins;
+ path = "HelloCordova/Plugins";
+ sourceTree = SOURCE_ROOT;
+ };
+ 308D052D1370CCF300D202BF /* icons */ = {
+ isa = PBXGroup;
+ children = (
+ 30C1856519D5FC0A00212699 /* icon-60@3x.png */,
+ 7E7966D41810823500FA85AD /* icon-40.png */,
+ 7E7966D51810823500FA85AD /* icon-40@2x.png */,
+ 7E7966D61810823500FA85AD /* icon-50.png */,
+ 7E7966D71810823500FA85AD /* icon-50@2x.png */,
+ 7E7966D81810823500FA85AD /* icon-60.png */,
+ 7E7966D91810823500FA85AD /* icon-60@2x.png */,
+ 7E7966DA1810823500FA85AD /* icon-76.png */,
+ 7E7966DB1810823500FA85AD /* icon-76@2x.png */,
+ 7E7966DC1810823500FA85AD /* icon-small.png */,
+ 7E7966DD1810823500FA85AD /* icon-small@2x.png */,
+ 30FC414816E50CA1004E6F35 /* icon-72@2x.png */,
+ 308D052E1370CCF300D202BF /* icon-72.png */,
+ 308D052F1370CCF300D202BF /* icon.png */,
+ 308D05301370CCF300D202BF /* icon@2x.png */,
+ );
+ path = icons;
+ sourceTree = "<group>";
+ };
+ 308D05311370CCF300D202BF /* splash */ = {
+ isa = PBXGroup;
+ children = (
+ 30B4F2FD19D5E07200D9F7D8 /* Default-667h.png */,
+ 30B4F2FE19D5E07200D9F7D8 /* Default-736h.png */,
+ 30B4F2FF19D5E07200D9F7D8 /* Default-Landscape-736h.png */,
+ D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */,
+ 3088BBB7154F3926009F9C59 /* Default-Landscape@2x~ipad.png */,
+ 3088BBB8154F3926009F9C59 /* Default-Landscape~ipad.png */,
+ 3088BBB9154F3926009F9C59 /* Default-Portrait@2x~ipad.png */,
+ 3088BBBA154F3926009F9C59 /* Default-Portrait~ipad.png */,
+ 3088BBBB154F3926009F9C59 /* Default@2x~iphone.png */,
+ 3088BBBC154F3926009F9C59 /* Default~iphone.png */,
+ );
+ path = splash;
+ sourceTree = "<group>";
+ };
+ EB87FDF11871DA420020F90C /* Staging */ = {
+ isa = PBXGroup;
+ children = (
+ F840E1F0165FE0F500CFE078 /* config.xml */,
+ 301BF56E109A69640062928A /* www */,
+ );
+ name = Staging;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 1D6058900D05DD3D006BFB54 /* HelloCordova */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "HelloCordova" */;
+ buildPhases = (
+ 304B58A110DAC018002A0835 /* Copy www directory */,
+ 1D60588D0D05DD3D006BFB54 /* Resources */,
+ 1D60588E0D05DD3D006BFB54 /* Sources */,
+ 1D60588F0D05DD3D006BFB54 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 301BF551109A68C00062928A /* PBXTargetDependency */,
+ );
+ name = "HelloCordova";
+ productName = "HelloCordova";
+ productReference = 1D6058910D05DD3D006BFB54 /* HelloCordova.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 29B97313FDCFA39411CA2CEA /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0510;
+ };
+ buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "__CLI__" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ en,
+ es,
+ de,
+ se,
+ );
+ mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
+ projectDirPath = "";
+ projectReferences = (
+ {
+ ProductGroup = 301BF52E109A57CC0062928A /* Products */;
+ ProjectRef = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */;
+ },
+ );
+ projectRoot = "";
+ targets = (
+ 1D6058900D05DD3D006BFB54 /* HelloCordova */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXReferenceProxy section */
+ 301BF535109A57CC0062928A /* libCordova.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libCordova.a;
+ remoteRef = 301BF534109A57CC0062928A /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+/* End PBXReferenceProxy section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 1D60588D0D05DD3D006BFB54 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 7E7966E41810823500FA85AD /* icon-76.png in Resources */,
+ 7E7966DF1810823500FA85AD /* icon-40@2x.png in Resources */,
+ 308D05371370CCF300D202BF /* icon-72.png in Resources */,
+ 30B4F30119D5E07200D9F7D8 /* Default-736h.png in Resources */,
+ 308D05381370CCF300D202BF /* icon.png in Resources */,
+ 308D05391370CCF300D202BF /* icon@2x.png in Resources */,
+ 302D95F214D2391D003F00A1 /* MainViewController.xib in Resources */,
+ 7E7966E01810823500FA85AD /* icon-50.png in Resources */,
+ 7E7966E31810823500FA85AD /* icon-60@2x.png in Resources */,
+ 7E7966E61810823500FA85AD /* icon-small.png in Resources */,
+ 3088BBBD154F3926009F9C59 /* Default-Landscape@2x~ipad.png in Resources */,
+ 3088BBBE154F3926009F9C59 /* Default-Landscape~ipad.png in Resources */,
+ 3088BBBF154F3926009F9C59 /* Default-Portrait@2x~ipad.png in Resources */,
+ 7E7966E71810823500FA85AD /* icon-small@2x.png in Resources */,
+ 3088BBC0154F3926009F9C59 /* Default-Portrait~ipad.png in Resources */,
+ 30B4F30019D5E07200D9F7D8 /* Default-667h.png in Resources */,
+ 7E7966DE1810823500FA85AD /* icon-40.png in Resources */,
+ 3088BBC1154F3926009F9C59 /* Default@2x~iphone.png in Resources */,
+ 7E7966E21810823500FA85AD /* icon-60.png in Resources */,
+ 3088BBC2154F3926009F9C59 /* Default~iphone.png in Resources */,
+ D4A0D8761607E02300AEF8BB /* Default-568h@2x~iphone.png in Resources */,
+ 30B4F30219D5E07200D9F7D8 /* Default-Landscape-736h.png in Resources */,
+ 30C1856619D5FC0A00212699 /* icon-60@3x.png in Resources */,
+ 7E7966E11810823500FA85AD /* icon-50@2x.png in Resources */,
+ 7E7966E51810823500FA85AD /* icon-76@2x.png in Resources */,
+ 30FC414916E50CA1004E6F35 /* icon-72@2x.png in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 304B58A110DAC018002A0835 /* Copy www directory */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Copy www directory";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "cordova/lib/copy-www-build-step.sh";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 1D60588E0D05DD3D006BFB54 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1D60589B0D05DD56006BFB54 /* main.m in Sources */,
+ 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */,
+ 302D95F114D2391D003F00A1 /* MainViewController.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 301BF551109A68C00062928A /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = CordovaLib;
+ targetProxy = 301BF550109A68C00062928A /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ 1D6058940D05DD3E006BFB54 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "HelloCordova/HelloCordova-Prefix.pch";
+ GCC_THUMB_SUPPORT = NO;
+ GCC_VERSION = "";
+ INFOPLIST_FILE = "HelloCordova/HelloCordova-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+ OTHER_LDFLAGS = (
+ "-weak_framework",
+ CoreFoundation,
+ "-weak_framework",
+ UIKit,
+ "-weak_framework",
+ AVFoundation,
+ "-weak_framework",
+ CoreMedia,
+ "-weak-lSystem",
+ "-ObjC",
+ );
+ PRODUCT_NAME = "HelloCordova";
+ TARGETED_DEVICE_FAMILY = "1";
+ };
+ name = Debug;
+ };
+ 1D6058950D05DD3E006BFB54 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COPY_PHASE_STRIP = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "HelloCordova/HelloCordova-Prefix.pch";
+ GCC_THUMB_SUPPORT = NO;
+ GCC_VERSION = "";
+ INFOPLIST_FILE = "HelloCordova/HelloCordova-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+ OTHER_LDFLAGS = (
+ "-weak_framework",
+ CoreFoundation,
+ "-weak_framework",
+ UIKit,
+ "-weak_framework",
+ AVFoundation,
+ "-weak_framework",
+ CoreMedia,
+ "-weak-lSystem",
+ "-ObjC",
+ );
+ PRODUCT_NAME = "HelloCordova";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ C01FCF4F08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_THUMB_SUPPORT = NO;
+ GCC_VERSION = "";
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"",
+ "\"$(OBJROOT)/UninstalledProducts/include\"",
+ "\"$(BUILT_PRODUCTS_DIR)\"",
+ );
+ IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+ ONLY_ACTIVE_ARCH = YES;
+ OTHER_LDFLAGS = (
+ "-weak_framework",
+ CoreFoundation,
+ "-weak_framework",
+ UIKit,
+ "-weak_framework",
+ AVFoundation,
+ "-weak_framework",
+ CoreMedia,
+ "-weak-lSystem",
+ "-ObjC",
+ );
+ SDKROOT = iphoneos;
+ SKIP_INSTALL = NO;
+ USER_HEADER_SEARCH_PATHS = "";
+ };
+ name = Debug;
+ };
+ C01FCF5008A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_THUMB_SUPPORT = NO;
+ GCC_VERSION = "";
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"",
+ "\"$(OBJROOT)/UninstalledProducts/include\"",
+ "\"$(BUILT_PRODUCTS_DIR)\"",
+ );
+ IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+ OTHER_LDFLAGS = (
+ "-weak_framework",
+ CoreFoundation,
+ "-weak_framework",
+ UIKit,
+ "-weak_framework",
+ AVFoundation,
+ "-weak_framework",
+ CoreMedia,
+ "-weak-lSystem",
+ "-ObjC",
+ );
+ SDKROOT = iphoneos;
+ SKIP_INSTALL = NO;
+ USER_HEADER_SEARCH_PATHS = "";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "HelloCordova" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1D6058940D05DD3E006BFB54 /* Debug */,
+ 1D6058950D05DD3E006BFB54 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4E08A954540054247B /* Build configuration list for PBXProject "__CLI__" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4F08A954540054247B /* Debug */,
+ C01FCF5008A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
diff --git a/test/pbxFile.js b/test/pbxFile.js
index 0e3c4ee..9a55b0a 100644
--- a/test/pbxFile.js
+++ b/test/pbxFile.js
@@ -1,74 +1,67 @@
var pbxFile = require('../lib/pbxFile');
-exports['lastType'] = {
+exports['lastKnownFileType'] = {
'should detect that a .m path means sourcecode.c.objc': function (test) {
var sourceFile = new pbxFile('Plugins/ChildBrowser.m');
- test.equal('sourcecode.c.objc', sourceFile.lastType);
+ test.equal('sourcecode.c.objc', sourceFile.lastKnownFileType);
test.done();
},
'should detect that a .h path means sourceFile.c.h': function (test) {
var sourceFile = new pbxFile('Plugins/ChildBrowser.h');
- test.equal('sourcecode.c.h', sourceFile.lastType);
+ test.equal('sourcecode.c.h', sourceFile.lastKnownFileType);
test.done();
},
'should detect that a .bundle path means "wrapper.plug-in"': function (test) {
var sourceFile = new pbxFile('Plugins/ChildBrowser.bundle');
- test.equal('"wrapper.plug-in"', sourceFile.lastType);
+ test.equal('wrapper.plug-in', sourceFile.lastKnownFileType);
test.done();
},
'should detect that a .xib path means file.xib': function (test) {
var sourceFile = new pbxFile('Plugins/ChildBrowser.xib');
- test.equal('file.xib', sourceFile.lastType);
+ test.equal('file.xib', sourceFile.lastKnownFileType);
test.done();
},
'should detect that a .dylib path means "compiled.mach-o.dylib"': function (test) {
var sourceFile = new pbxFile('libsqlite3.dylib');
- test.equal('"compiled.mach-o.dylib"', sourceFile.lastType);
+ test.equal('compiled.mach-o.dylib', sourceFile.lastKnownFileType);
test.done();
},
'should detect that a .framework path means wrapper.framework': function (test) {
var sourceFile = new pbxFile('MessageUI.framework');
- test.equal('wrapper.framework', sourceFile.lastType);
+ test.equal('wrapper.framework', sourceFile.lastKnownFileType);
test.done();
},
- 'should detect that a .framework/.a path means archive.ar': function (test) {
- var sourceFile = new pbxFile('MessageUI.framework/libGoogleAnalytics.a');
-
- test.equal('archive.ar', sourceFile.lastType);
- test.done();
- },
-
'should detect that a .a path means archive.ar': function (test) {
var sourceFile = new pbxFile('libGoogleAnalytics.a');
- test.equal('archive.ar', sourceFile.lastType);
+ test.equal('archive.ar', sourceFile.lastKnownFileType);
test.done();
},
- 'should allow lastType to be overridden': function (test) {
+ 'should allow lastKnownFileType to be overridden': function (test) {
var sourceFile = new pbxFile('Plugins/ChildBrowser.m',
- { lastType: 'somestupidtype' });
+ { lastKnownFileType: 'somestupidtype' });
- test.equal('somestupidtype', sourceFile.lastType);
+ test.equal('somestupidtype', sourceFile.lastKnownFileType);
test.done();
},
- 'should set lastType to unknown if undetectable': function (test) {
+ 'should set lastKnownFileType to unknown if undetectable': function (test) {
var sourceFile = new pbxFile('Plugins/ChildBrowser.guh');
- test.equal('unknown', sourceFile.lastType);
+ test.equal('unknown', sourceFile.lastKnownFileType);
test.done();
}
}
diff --git a/test/pbxProject.js b/test/pbxProject.js
index 77786b7..eacb61b 100644
--- a/test/pbxProject.js
+++ b/test/pbxProject.js
@@ -177,6 +177,90 @@
}
}
+exports['addBuildProperty function'] = {
+ setUp:function(callback) {
+ callback();
+ },
+ tearDown:function(callback) {
+ fs.writeFileSync(bcpbx, original_pbx, 'utf-8');
+ callback();
+ },
+ 'should add 4 build properties in the .pbxproj file': function (test) {
+ var myProj = new pbx('test/parser/projects/build-config.pbxproj');
+ myProj.parse(function(err, hash) {
+ myProj.addBuildProperty('ENABLE_BITCODE', 'NO');
+ var newContents = myProj.writeSync();
+ test.equal(newContents.match(/ENABLE_BITCODE\s*=\s*NO/g).length, 4);
+ test.done();
+ });
+ },
+ 'should add 2 build properties in the .pbxproj file for specific build': function (test) {
+ var myProj = new pbx('test/parser/projects/build-config.pbxproj');
+ myProj.parse(function(err, hash) {
+ myProj.addBuildProperty('ENABLE_BITCODE', 'NO', 'Release');
+ var newContents = myProj.writeSync();
+ test.equal(newContents.match(/ENABLE_BITCODE\s*=\s*NO/g).length, 2);
+ test.done();
+ });
+ },
+ 'should not add build properties in the .pbxproj file for nonexist build': function (test) {
+ var myProj = new pbx('test/parser/projects/build-config.pbxproj');
+ myProj.parse(function(err, hash) {
+ myProj.addBuildProperty('ENABLE_BITCODE', 'NO', 'nonexist');
+ var newContents = myProj.writeSync();
+ test.ok(!newContents.match(/ENABLE_BITCODE\s*=\s*NO/g));
+ test.done();
+ });
+ }
+}
+
+exports['removeBuildProperty function'] = {
+ setUp:function(callback) {
+ callback();
+ },
+ tearDown:function(callback) {
+ fs.writeFileSync(bcpbx, original_pbx, 'utf-8');
+ callback();
+ },
+ 'should remove all build properties in the .pbxproj file': function (test) {
+ var myProj = new pbx('test/parser/projects/build-config.pbxproj');
+ myProj.parse(function(err, hash) {
+ myProj.removeBuildProperty('IPHONEOS_DEPLOYMENT_TARGET');
+ var newContents = myProj.writeSync();
+ test.ok(!newContents.match(/IPHONEOS_DEPLOYMENT_TARGET/));
+ test.done();
+ });
+ },
+ 'should remove specific build properties in the .pbxproj file': function (test) {
+ var myProj = new pbx('test/parser/projects/build-config.pbxproj');
+ myProj.parse(function(err, hash) {
+ myProj.removeBuildProperty('IPHONEOS_DEPLOYMENT_TARGET', 'Debug');
+ var newContents = myProj.writeSync();
+ test.equal(newContents.match(/IPHONEOS_DEPLOYMENT_TARGET/g).length, 2);
+ test.done();
+ });
+ },
+ 'should not remove any build properties in the .pbxproj file': function (test) {
+ var myProj = new pbx('test/parser/projects/build-config.pbxproj');
+ myProj.parse(function(err, hash) {
+ myProj.removeBuildProperty('IPHONEOS_DEPLOYMENT_TARGET', 'notexist');
+ var newContents = myProj.writeSync();
+ test.equal(newContents.match(/IPHONEOS_DEPLOYMENT_TARGET/g).length, 4);
+ test.done();
+ });
+ },
+ 'should fine with remove inexist build properties in the .pbxproj file': function (test) {
+ var myProj = new pbx('test/parser/projects/build-config.pbxproj');
+ myProj.parse(function(err, hash) {
+ myProj.removeBuildProperty('ENABLE_BITCODE');
+ var newContents = myProj.writeSync();
+ test.ok(!newContents.match(/ENABLE_BITCODE/));
+ test.done();
+ });
+ }
+
+}
+
exports['productName field'] = {
'should return the product name': function (test) {
var newProj = new pbx('.');
diff --git a/test/removeResourceFile.js b/test/removeResourceFile.js
index 7260aa5..25b1347 100644
--- a/test/removeResourceFile.js
+++ b/test/removeResourceFile.js
@@ -140,7 +140,7 @@
test.equal(fileRefEntry.isa, 'PBXFileReference');
test.equal(fileRefEntry.fileEncoding, undefined);
- test.equal(fileRefEntry.lastKnownFileType, '"wrapper.plug-in"');
+ test.equal(fileRefEntry.lastKnownFileType, 'wrapper.plug-in');
test.equal(fileRefEntry.name, '"assets.bundle"');
test.equal(fileRefEntry.path, '"Resources/assets.bundle"');
test.equal(fileRefEntry.sourceTree, '"<group>"');