From d61c312a0817d0d5fc1e0f93679f71941377a484 Mon Sep 17 00:00:00 2001 From: Fatme Havaluova Date: Wed, 24 Jun 2015 18:18:42 +0300 Subject: [PATCH 01/69] Fix unknown lastKnownFileType Fix quotes --- lib/pbxFile.js | 1 + lib/pbxProject.js | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/pbxFile.js b/lib/pbxFile.js index 9553bfb..98206a5 100644 --- a/lib/pbxFile.js +++ b/lib/pbxFile.js @@ -38,6 +38,7 @@ var FILETYPE_BY_EXTENSION = { octest: 'wrapper.cfbundle', pch: 'sourcecode.c.h', plist: 'text.plist.xml', + png: "image.png", sh: 'text.script.sh', swift: 'sourcecode.swift', tbd: 'sourcecode.text-based-dylib-definition', diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 0e0f8f9..11e790c 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -1520,8 +1520,8 @@ function pbxBuildFileObj(file) { function pbxFileReferenceObj(file) { var fileObject = { isa: "PBXFileReference", - name: "\"" + file.basename + "\"", - path: "\"" + file.path.replace(/\\/g, '/') + "\"", + name: file.basename, + path: file.path, sourceTree: file.sourceTree, fileEncoding: file.fileEncoding, lastKnownFileType: file.lastKnownFileType, @@ -1529,6 +1529,16 @@ function pbxFileReferenceObj(file) { includeInIndex: file.includeInIndex }; + if(fileObject.name.indexOf("\"") !== -1) { + fileObject.name = fileObject.name.replace(/\"/g, "\\\""); + fileObject.path = fileObject.path.replace(/\"/g, "\\\""); + } + + if(!file.basename.match(/^[a-zA-Z0-9_\.\$]+\.[a-zA-Z]+$/)) { + fileObject.name = "\"" + fileObject.name + "\""; + fileObject.path = "\"" + fileObject.path + "\""; + } + return fileObject; } From 053d70c759c948df012d9ae8b34179d4717d99ae Mon Sep 17 00:00:00 2001 From: Dimitar Kerezov Date: Tue, 30 Jun 2015 16:41:24 +0300 Subject: [PATCH 02/69] Fix path/name quotation Those properties should be surrounded by quotation marks based on appearance of special characters in path and basename properties respectively. They are independent of one another. --- lib/pbxProject.js | 8 +++- test/pbxProject.js | 100 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 11e790c..cbfd1b8 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -26,7 +26,8 @@ var util = require('util'), fs = require('fs'), parser = require('./parser/pbxproj'), plist = require('simple-plist'), - COMMENT_KEY = /_comment$/ + COMMENT_KEY = /_comment$/, + NO_SPECIAL_SYMBOLS = /^[a-zA-Z0-9_\.\$]+\.[a-zA-Z]+$/; function pbxProject(filename) { if (!(this instanceof pbxProject)) @@ -1534,8 +1535,11 @@ function pbxFileReferenceObj(file) { fileObject.path = fileObject.path.replace(/\"/g, "\\\""); } - if(!file.basename.match(/^[a-zA-Z0-9_\.\$]+\.[a-zA-Z]+$/)) { + if(!file.basename.match(NO_SPECIAL_SYMBOLS)) { fileObject.name = "\"" + fileObject.name + "\""; + } + + if(!file.path.match(NO_SPECIAL_SYMBOLS)) { fileObject.path = "\"" + fileObject.path + "\""; } diff --git a/test/pbxProject.js b/test/pbxProject.js index c076b96..176f836 100644 --- a/test/pbxProject.js +++ b/test/pbxProject.js @@ -328,3 +328,103 @@ exports['hasFile'] = { test.done() } } + +exports['addToPbxFileReferenceSection'] = { + 'should not quote name when no special characters present in basename': function (test) { + var newProj = new pbx('.'); + newProj.hash = jsonProject, + file = { + uuid: newProj.generateUuid(), + fileRef: newProj.generateUuid(), + isa: 'PBXFileReference', + explicitFileType: 'wrapper.application', + includeInIndex: 0, + basename: "SomeFile.m", + path: "SomePath.m", + sourceTree: 'BUILT_PRODUCTS_DIR' + }, + fileRefSection = newProj.pbxFileReferenceSection(); + + newProj.addToPbxFileReferenceSection(file); + test.equal(fileRefSection[file.fileRef].name, "SomeFile.m"); + test.done(); + }, + 'should quote name when special characters present in basename': function (test) { + var newProj = new pbx('.'); + newProj.hash = jsonProject, + file = { + uuid: newProj.generateUuid(), + fileRef: newProj.generateUuid(), + isa: 'PBXFileReference', + explicitFileType: 'wrapper.application', + includeInIndex: 0, + basename: "Some File.m", + path: "SomePath.m", + sourceTree: 'BUILT_PRODUCTS_DIR' + }, + fileRefSection = newProj.pbxFileReferenceSection(); + + newProj.addToPbxFileReferenceSection(file); + test.equal(fileRefSection[file.fileRef].name, '"Some File.m"'); + test.done(); + }, + 'should not quote path when no special characters present in path': function (test) { + var newProj = new pbx('.'); + newProj.hash = jsonProject, + file = { + uuid: newProj.generateUuid(), + fileRef: newProj.generateUuid(), + isa: 'PBXFileReference', + explicitFileType: 'wrapper.application', + includeInIndex: 0, + basename: "SomeFile.m", + path: "SomePath.m", + sourceTree: 'BUILT_PRODUCTS_DIR' + }, + fileRefSection = newProj.pbxFileReferenceSection(); + + newProj.addToPbxFileReferenceSection(file); + test.equal(fileRefSection[file.fileRef].path, "SomePath.m"); + test.done(); + }, + 'should quote path when special characters present in path': function (test) { + var newProj = new pbx('.'); + newProj.hash = jsonProject, + file = { + uuid: newProj.generateUuid(), + fileRef: newProj.generateUuid(), + isa: 'PBXFileReference', + explicitFileType: 'wrapper.application', + includeInIndex: 0, + basename: "SomeFile.m", + path: "SomeFolder/Some Path.m", + sourceTree: 'BUILT_PRODUCTS_DIR' + }, + fileRefSection = newProj.pbxFileReferenceSection(); + + newProj.addToPbxFileReferenceSection(file); + test.equal(fileRefSection[file.fileRef].path, '"SomeFolder/Some Path.m"'); + test.done(); + }, + 'should quote path and name when special characters present in path and basename': function (test) { + var newProj = new pbx('.'); + newProj.hash = jsonProject, + file = { + uuid: newProj.generateUuid(), + fileRef: newProj.generateUuid(), + isa: 'PBXFileReference', + explicitFileType: 'wrapper.application', + includeInIndex: 0, + basename: "Some File.m", + path: "SomeFolder/Some Path.m", + sourceTree: 'BUILT_PRODUCTS_DIR' + }, + fileRefSection = newProj.pbxFileReferenceSection(); + + newProj.addToPbxFileReferenceSection(file); + test.equal(fileRefSection[file.fileRef].name, '"Some File.m"'); + test.equal(fileRefSection[file.fileRef].path, '"SomeFolder/Some Path.m"'); + test.done(); + } +} + From 1a410c1b1a644f8eb926e4ab718ebe2c4f8da256 Mon Sep 17 00:00:00 2001 From: Toma Popov Date: Mon, 7 Sep 2015 21:16:24 +0300 Subject: [PATCH 03/69] Implement relative to project root search paths. --- lib/pbxProject.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index cbfd1b8..28a7718 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -1650,6 +1650,10 @@ function correctForPath(file, project, group) { } function searchPathForFile(file, proj) { + if (file.relativePath) { + return '"\$(SRCROOT)/' + file.relativePath + '\"'; + } + var plugins = proj.pbxGroupByName('Plugins'), pluginsPath = plugins ? plugins.path : null, fileDir = path.dirname(file.path); From 52fa3f1d7c0c32c8a818d0bde3ca64d8f76b8392 Mon Sep 17 00:00:00 2001 From: Teodor Dermendzhiev Date: Fri, 18 May 2018 18:57:11 +0300 Subject: [PATCH 04/69] feat: Add support various file extensions and export filetypes for pbxFile module --- lib/pbxFile.js | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/pbxFile.js b/lib/pbxFile.js index 98206a5..0a7611b 100644 --- a/lib/pbxFile.js +++ b/lib/pbxFile.js @@ -29,10 +29,20 @@ var FILETYPE_BY_EXTENSION = { app: 'wrapper.application', appex: 'wrapper.app-extension', bundle: 'wrapper.plug-in', + c: 'sourcecode.c.c', + cc: 'sourcecode.cpp.cpp', + cpp: 'sourcecode.cpp.cpp', + cxx: 'sourcecode.cpp.cpp', + 'c++': 'sourcecode.cpp.cpp', dylib: 'compiled.mach-o.dylib', framework: 'wrapper.framework', h: 'sourcecode.c.h', + hh: 'sourcecode.cpp.h', + hpp: 'sourcecode.cpp.h', + hxx: 'sourcecode.cpp.h', + 'h++': 'sourcecode.cpp.h', m: 'sourcecode.c.objc', + mm: 'sourcecode.cpp.objcpp', markdown: 'text', mdimporter: 'wrapper.cfbundle', octest: 'wrapper.cfbundle', @@ -57,8 +67,11 @@ var FILETYPE_BY_EXTENSION = { 'wrapper.framework': 'Frameworks', 'embedded.framework': 'Embed Frameworks', 'sourcecode.c.h': 'Resources', + 'sourcecode.c.c': 'Sources', 'sourcecode.c.objc': 'Sources', - 'sourcecode.swift': 'Sources' + 'sourcecode.swift': 'Sources', + 'sourcecode.cpp.cpp': 'Sources', + 'sourcecode.cpp.objcpp': 'Sources' }, PATH_BY_FILETYPE = { 'compiled.mach-o.dylib': 'usr/lib/', @@ -73,7 +86,11 @@ var FILETYPE_BY_EXTENSION = { ENCODING_BY_FILETYPE = { 'sourcecode.c.h': 4, 'sourcecode.c.h': 4, + 'sourcecode.cpp.h': 4, + 'sourcecode.c.c': 4, 'sourcecode.c.objc': 4, + 'sourcecode.cpp.cpp': 4, + 'sourcecode.cpp.objcpp': 4, 'sourcecode.swift': 4, 'text': 4, 'text.plist.xml': 4, @@ -231,4 +248,7 @@ function pbxFile(filepath, opt) { } } -module.exports = pbxFile; +module.exports = { + pbxFile: pbxFile, + fileTypes: fileTypes +} From 73bb80925643f39b3ed66fd1be9b55efaf77ca29 Mon Sep 17 00:00:00 2001 From: Teodor Dermendzhiev Date: Fri, 18 May 2018 19:06:12 +0300 Subject: [PATCH 05/69] feat: Implement adding and removing of pbx groups *support for c++ files added *recursively add pbxGroup and its children *recursively remove pbxGroup and its children *make sure pbx group name is not duplicated on adding new group --- lib/pbxProject.js | 110 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 87 insertions(+), 23 deletions(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 28a7718..8e86b55 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -18,22 +18,25 @@ var util = require('util'), f = util.format, EventEmitter = require('events').EventEmitter, - path = require('path'), + $path = require('path'), uuid = require('uuid'), fork = require('child_process').fork, pbxWriter = require('./pbxWriter'), - pbxFile = require('./pbxFile'), + pbxFile = require('./pbxFile').pbxFile, + pbxFileTypes = require('./pbxFile').fileTypes, fs = require('fs'), parser = require('./parser/pbxproj'), plist = require('simple-plist'), COMMENT_KEY = /_comment$/, - NO_SPECIAL_SYMBOLS = /^[a-zA-Z0-9_\.\$]+\.[a-zA-Z]+$/; + NO_SPECIAL_SYMBOLS = /^[a-zA-Z0-9_\.\$]+\.[a-zA-Z]+$/, + HEADER_FILE_TYPE_SUFFIX = ".h", + SOURCE_CODE_FILE_TYPE_PREFIX = "sourcecode."; function pbxProject(filename) { if (!(this instanceof pbxProject)) return new pbxProject(filename); - this.filepath = path.resolve(filename) + this.filepath = $path.resolve(filename) } util.inherits(pbxProject, EventEmitter) @@ -492,17 +495,37 @@ pbxProject.prototype.removeFromPbxBuildFileSection = function(file) { } } -pbxProject.prototype.addPbxGroup = function(filePathsArray, name, path, sourceTree) { +pbxProject.prototype.findMainPbxGroup = function () { + var groups = this.hash.project.objects['PBXGroup']; + var candidates = []; + for (var key in groups) { + if (!groups[key].path && !groups[key].name && groups[key].isa) { + candidates.push(groups[key]); + } + } + if (candidates.length == 1) { + return candidates[0]; + } + + return null; +} + +pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceTree, opt) { + + var oldGroup = this.pbxGroupByName(name); + if (oldGroup) { + this.removePbxGroup(name, path); + } + var groups = this.hash.project.objects['PBXGroup'], - pbxGroupUuid = this.generateUuid(), + pbxGroupUuid = opt.uuid || this.generateUuid(), commentKey = f("%s_comment", pbxGroupUuid), pbxGroup = { isa: 'PBXGroup', children: [], name: name, - path: path, sourceTree: sourceTree ? sourceTree : '""' - }, + },//path is mandatory only for the main group fileReferenceSection = this.pbxFileReferenceSection(), filePathToReference = {}; @@ -527,12 +550,27 @@ pbxProject.prototype.addPbxGroup = function(filePathsArray, name, path, sourceTr continue; } - var file = new pbxFile(filePath); - file.uuid = this.generateUuid(); - file.fileRef = this.generateUuid(); - this.addToPbxFileReferenceSection(file); // PBXFileReference - this.addToPbxBuildFileSection(file); // PBXBuildFile - pbxGroup.children.push(pbxGroupChild(file)); + var srcRootPath = $path.dirname($path.dirname(this.filepath)); + var file = new pbxFile($path.relative(srcRootPath, filePath)); + if (fs.lstatSync(filePath).isDirectory()) { + file.uuid = this.generateUuid(); + file.fileRef = file.uuid; + this.addToPbxFileReferenceSection(file); // PBXFileReference + this.addToPbxBuildFileSection(file); + pbxGroup.children.push(pbxGroupChild(file)); + var files = fs.readdirSync(filePath).map(p => $path.join(filePath, p)); + this.addPbxGroup(files, $path.basename(filePath), filePath, null, {uuid: file.uuid}); + }else if (file.lastType.startsWith(SOURCE_CODE_FILE_TYPE_PREFIX)) { + file.uuid = this.generateUuid(); + file.fileRef = this.generateUuid(); + this.addToPbxFileReferenceSection(file); // PBXFileReference + this.addToPbxBuildFileSection(file); // PBXBuildFile + if (!file.lastType.endsWith(HEADER_FILE_TYPE_SUFFIX)) { + this.addToPbxSourcesBuildPhase(file); + } + pbxGroup.children.push(pbxGroupChild(file)); + } + } if (groups) { @@ -540,10 +578,36 @@ pbxProject.prototype.addPbxGroup = function(filePathsArray, name, path, sourceTr groups[commentKey] = name; } - return { uuid: pbxGroupUuid, pbxGroup: pbxGroup }; + if (opt.isMain) { + let mainGroup = this.findMainPbxGroup(); + if (mainGroup) { + var file = new pbxFile($path.relative(this.filepath, path)); + file.fileRef = pbxGroupUuid; + mainGroup.children.push(pbxGroupChild(file)); + } + } + + return {uuid: pbxGroupUuid, pbxGroup: pbxGroup}; } -pbxProject.prototype.removePbxGroup = function (groupName) { +pbxProject.prototype.removePbxGroup = function(groupName, path) { + var group = this.pbxGroupByName(groupName); + if (!group) { + return; + } + + var children = group.children; + + for(i in children) { + var file = new pbxFile($path.join(path, children[i].comment)); + file.fileRef = children[i].value; + file.uuid = file.fileRef; + this.removePbxGroup(children[i].comment, $path.join(path, children[i].comment)); + this.removeFromPbxFileReferenceSection(file); + this.removeFromPbxBuildFileSection(file); + this.removeFromPbxSourcesBuildPhase(file); + } + var section = this.hash.project.objects['PBXGroup'], key, itemKey; @@ -616,12 +680,12 @@ pbxProject.prototype.addToXcVersionGroupSection = function(file) { isa: 'XCVersionGroup', children: file.models.map(function (el) { return el.fileRef; }), currentVersion: file.currentModel.fileRef, - name: path.basename(file.path), + name: $path.basename(file.path), path: file.path, sourceTree: '""', versionGroupType: 'wrapper.xcdatamodel' }; - this.xcVersionGroupSection()[commentKey] = path.basename(file.path); + this.xcVersionGroupSection()[commentKey] = $path.basename(file.path); } } @@ -1416,7 +1480,7 @@ pbxProject.prototype.addTarget = function(name, type, subfolder) { isa: 'XCBuildConfiguration', buildSettings: { GCC_PREPROCESSOR_DEFINITIONS: ['"DEBUG=1"', '"$(inherited)"'], - INFOPLIST_FILE: '"' + path.join(targetSubfolder, targetSubfolder + '-Info.plist' + '"'), + 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' @@ -1426,7 +1490,7 @@ pbxProject.prototype.addTarget = function(name, type, subfolder) { name: 'Release', isa: 'XCBuildConfiguration', buildSettings: { - INFOPLIST_FILE: '"' + path.join(targetSubfolder, targetSubfolder + '-Info.plist' + '"'), + 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' @@ -1616,7 +1680,7 @@ function pbxBuildFileComment(file) { } function pbxFileReferenceComment(file) { - return file.basename || path.basename(file.path); + return file.basename || $path.basename(file.path); } function pbxNativeTargetComment(target) { @@ -1656,7 +1720,7 @@ function searchPathForFile(file, proj) { var plugins = proj.pbxGroupByName('Plugins'), pluginsPath = plugins ? plugins.path : null, - fileDir = path.dirname(file.path); + fileDir = $path.dirname(file.path); if (fileDir == '.') { fileDir = ''; @@ -2071,7 +2135,7 @@ pbxProject.prototype.addDataModelDocument = function(filePath, group, opt) { var modelFiles = fs.readdirSync(file.path); for (var index in modelFiles) { var modelFileName = modelFiles[index]; - var modelFilePath = path.join(filePath, modelFileName); + var modelFilePath = $path.join(filePath, modelFileName); if (modelFileName == '.xccurrentversion') { currentVersionName = plist.readFileSync(modelFilePath)._XCCurrentVersionName; From 176df7f785ea489adbc7ef7a03b702bb7f5260df Mon Sep 17 00:00:00 2001 From: Teodor Dermendzhiev Date: Tue, 22 May 2018 10:39:53 +0300 Subject: [PATCH 06/69] feat: add support for header search path deletion by string --- lib/pbxProject.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 8e86b55..b3d203f 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -591,10 +591,10 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT } pbxProject.prototype.removePbxGroup = function(groupName, path) { - var group = this.pbxGroupByName(groupName); - if (!group) { - return; - } + var group = this.pbxGroupByName(groupName); + if (!group) { + return; + } var children = group.children; @@ -1310,7 +1310,7 @@ pbxProject.prototype.removeFromHeaderSearchPaths = function(file) { INHERITED = '"$(inherited)"', SEARCH_PATHS = 'HEADER_SEARCH_PATHS', config, buildSettings, searchPaths; - var new_path = searchPathForFile(file, this); + var new_path = typeof file === 'string' ? file : searchPathForFile(file, this); for (config in configurations) { buildSettings = configurations[config].buildSettings; From bb83017c1adb6d5d7ea778a922714d324a95f14e Mon Sep 17 00:00:00 2001 From: Teodor Dermendzhiev Date: Wed, 23 May 2018 16:05:45 +0300 Subject: [PATCH 07/69] bugfix: Remove group reference from root group after group removal --- lib/pbxFile.js | 2 +- lib/pbxProject.js | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/pbxFile.js b/lib/pbxFile.js index 0a7611b..38ac741 100644 --- a/lib/pbxFile.js +++ b/lib/pbxFile.js @@ -204,7 +204,7 @@ function defaultGroup(fileRef) { function pbxFile(filepath, opt) { var opt = opt || {}; - this.basename = path.basename(filepath); + this.basename = opt.basename || path.basename(filepath); this.lastKnownFileType = opt.lastKnownFileType || detectType(filepath); this.group = detectGroup(this, opt); diff --git a/lib/pbxProject.js b/lib/pbxProject.js index b3d203f..75c7ca0 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -581,7 +581,7 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT if (opt.isMain) { let mainGroup = this.findMainPbxGroup(); if (mainGroup) { - var file = new pbxFile($path.relative(this.filepath, path)); + var file = new pbxFile($path.relative(this.filepath, path), {basename: name}); file.fileRef = pbxGroupUuid; mainGroup.children.push(pbxGroupChild(file)); } @@ -608,6 +608,13 @@ pbxProject.prototype.removePbxGroup = function(groupName, path) { this.removeFromPbxSourcesBuildPhase(file); } + var mainGroupChildren = this.findMainPbxGroup().children, i; + for(i in mainGroupChildren) { + if (mainGroupChildren[i].comment == name) { + mainGroupChildren.splice(i, 1); + } + } + var section = this.hash.project.objects['PBXGroup'], key, itemKey; From 490024f1f47771b756e3decf8606d53dfd6039dc Mon Sep 17 00:00:00 2001 From: Teodor Dermendzhiev Date: Wed, 23 May 2018 16:45:51 +0300 Subject: [PATCH 08/69] Bump version --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index b25fa48..70c4e53 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,8 @@ "author": "Apache Software Foundation", "name": "xcode", "description": "parser for xcodeproj/project.pbxproj files", - "version": "2.0.1-dev", - "main": "index.js", + "main":"index.js", + "version": "1.5.0-NativeScript", "repository": { "url": "https://github.com/apache/cordova-node-xcode.git" }, From bfbef40b7317110b7cce18de145dd2878ad1b7c3 Mon Sep 17 00:00:00 2001 From: Martin Bektchiev Date: Fri, 25 May 2018 18:21:19 +0300 Subject: [PATCH 09/69] fix: Add C++ Source files to the Sources group They were wrongly being added to Resources. --- lib/pbxFile.js | 14 ++++++++++++-- lib/pbxProject.js | 15 +++++++-------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/lib/pbxFile.js b/lib/pbxFile.js index 38ac741..fa0fb68 100644 --- a/lib/pbxFile.js +++ b/lib/pbxFile.js @@ -22,7 +22,9 @@ var DEFAULT_SOURCETREE = '""', DEFAULT_PRODUCT_SOURCETREE = 'BUILT_PRODUCTS_DIR', DEFAULT_FILEENCODING = 4, DEFAULT_GROUP = 'Resources', - DEFAULT_FILETYPE = 'unknown'; + DEFAULT_FILETYPE = 'unknown', + HEADER_FILE_TYPE_SUFFIX = ".h", + SOURCE_CODE_FILE_TYPE_PREFIX = "sourcecode."; var FILETYPE_BY_EXTENSION = { a: 'archive.ar', @@ -99,6 +101,13 @@ var FILETYPE_BY_EXTENSION = { 'text.plist.strings': 4 }; +function isSourceOrHeaderFileType(fileType) { + return fileType.startsWith(SOURCE_CODE_FILE_TYPE_PREFIX); +} + +function isHeaderFileType(fileType) { + return fileType.endsWith(HEADER_FILE_TYPE_SUFFIX); +} function unquoted(text){ return text == null ? '' : text.replace (/(^")|("$)/g, '') @@ -250,5 +259,6 @@ function pbxFile(filepath, opt) { module.exports = { pbxFile: pbxFile, - fileTypes: fileTypes + isSourceOrHeaderFileType, + isHeaderFileType } diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 75c7ca0..0519e31 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -23,14 +23,13 @@ var util = require('util'), fork = require('child_process').fork, pbxWriter = require('./pbxWriter'), pbxFile = require('./pbxFile').pbxFile, - pbxFileTypes = require('./pbxFile').fileTypes, + isSourceOrHeaderFileType = require('./pbxFile').isSourceOrHeaderFileType, + isHeaderFileType = require('./pbxFile').isHeaderFileType, fs = require('fs'), parser = require('./parser/pbxproj'), plist = require('simple-plist'), COMMENT_KEY = /_comment$/, - NO_SPECIAL_SYMBOLS = /^[a-zA-Z0-9_\.\$]+\.[a-zA-Z]+$/, - HEADER_FILE_TYPE_SUFFIX = ".h", - SOURCE_CODE_FILE_TYPE_PREFIX = "sourcecode."; + NO_SPECIAL_SYMBOLS = /^[a-zA-Z0-9_\.\$]+\.[a-zA-Z]+$/; function pbxProject(filename) { if (!(this instanceof pbxProject)) @@ -560,12 +559,12 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT pbxGroup.children.push(pbxGroupChild(file)); var files = fs.readdirSync(filePath).map(p => $path.join(filePath, p)); this.addPbxGroup(files, $path.basename(filePath), filePath, null, {uuid: file.uuid}); - }else if (file.lastType.startsWith(SOURCE_CODE_FILE_TYPE_PREFIX)) { + }else if (isSourceOrHeaderFileType(file.lastType)) { file.uuid = this.generateUuid(); file.fileRef = this.generateUuid(); this.addToPbxFileReferenceSection(file); // PBXFileReference this.addToPbxBuildFileSection(file); // PBXBuildFile - if (!file.lastType.endsWith(HEADER_FILE_TYPE_SUFFIX)) { + if (!isHeaderFileType(file.lastType)) { this.addToPbxSourcesBuildPhase(file); } pbxGroup.children.push(pbxGroupChild(file)); @@ -1605,11 +1604,11 @@ function pbxFileReferenceObj(file) { fileObject.name = fileObject.name.replace(/\"/g, "\\\""); fileObject.path = fileObject.path.replace(/\"/g, "\\\""); } - + if(!file.basename.match(NO_SPECIAL_SYMBOLS)) { fileObject.name = "\"" + fileObject.name + "\""; } - + if(!file.path.match(NO_SPECIAL_SYMBOLS)) { fileObject.path = "\"" + fileObject.path + "\""; } From 81e03fbea06dede91e224969547968438dc96c63 Mon Sep 17 00:00:00 2001 From: Martin Bektchiev Date: Fri, 25 May 2018 18:21:46 +0300 Subject: [PATCH 10/69] chore: Bump version to 1.5.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 70c4e53..4fc384d 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "name": "xcode", "description": "parser for xcodeproj/project.pbxproj files", "main":"index.js", - "version": "1.5.0-NativeScript", + "version": "1.5.1-NativeScript", "repository": { "url": "https://github.com/apache/cordova-node-xcode.git" }, From 71f488cbb2a2ea03cfe83a6b0c98e0a427397279 Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 4 Jul 2018 16:44:31 +0300 Subject: [PATCH 11/69] Fix file references inside .pbxproject --- lib/pbxProject.js | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 0519e31..b4afce1 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -1303,11 +1303,7 @@ pbxProject.prototype.addToLibrarySearchPaths = function(file) { buildSettings['LIBRARY_SEARCH_PATHS'] = [INHERITED]; } - if (typeof file === 'string') { - buildSettings['LIBRARY_SEARCH_PATHS'].push(file); - } else { - buildSettings['LIBRARY_SEARCH_PATHS'].push(searchPathForFile(file, this)); - } + buildSettings['LIBRARY_SEARCH_PATHS'].push(searchPathForFile(file, this)); } } @@ -1316,7 +1312,7 @@ pbxProject.prototype.removeFromHeaderSearchPaths = function(file) { INHERITED = '"$(inherited)"', SEARCH_PATHS = 'HEADER_SEARCH_PATHS', config, buildSettings, searchPaths; - var new_path = typeof file === 'string' ? file : searchPathForFile(file, this); + var new_path = searchPathForFile(file, this); for (config in configurations) { buildSettings = configurations[config].buildSettings; @@ -1351,11 +1347,7 @@ pbxProject.prototype.addToHeaderSearchPaths = function(file) { buildSettings['HEADER_SEARCH_PATHS'] = [INHERITED]; } - if (typeof file === 'string') { - buildSettings['HEADER_SEARCH_PATHS'].push(file); - } else { - buildSettings['HEADER_SEARCH_PATHS'].push(searchPathForFile(file, this)); - } + buildSettings['HEADER_SEARCH_PATHS'].push(searchPathForFile(file, this)); } } @@ -1720,8 +1712,27 @@ function correctForPath(file, project, group) { } function searchPathForFile(file, proj) { + const getPathString = (filePath) => { + return `"\\"${filePath}\\""`; + } + + const getRelativePathString = (filePath) => { + return getPathString(`$(SRCROOT)/${filePath}`); + } + + if (typeof file === 'string') { + const relativeFilePath = file; + + if ($path.isAbsolute(file)) { + const srcRoot = $path.dirname($path.dirname(proj.filepath)); + relativeFilePath = $path.relative(srcRoot, file); + } + + return getRelativePathString(relativeFilePath); + } + if (file.relativePath) { - return '"\$(SRCROOT)/' + file.relativePath + '\"'; + return getRelativePathString(file.relativePath); } var plugins = proj.pbxGroupByName('Plugins'), @@ -1735,11 +1746,11 @@ function searchPathForFile(file, proj) { } if (file.plugin && pluginsPath) { - return '"\\"$(SRCROOT)/' + unquote(pluginsPath) + '\\""'; + return getRelativePathString(unquote(pluginsPath)); } else if (file.customFramework && file.dirname) { - return '"\\"' + file.dirname + '\\""'; + return getPathString(file.dirname); } else { - return '"\\"$(SRCROOT)/' + proj.productName + fileDir + '\\""'; + return getRelativePathString(proj.productName + fileDir); } } From c947e417bc65a2443aec2a9080cce54b602da3f0 Mon Sep 17 00:00:00 2001 From: Fatme Date: Thu, 5 Jul 2018 12:46:35 +0300 Subject: [PATCH 12/69] Update version to 1.5.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4fc384d..2398b84 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "name": "xcode", "description": "parser for xcodeproj/project.pbxproj files", "main":"index.js", - "version": "1.5.1-NativeScript", + "version": "1.5.2-NativeScript", "repository": { "url": "https://github.com/apache/cordova-node-xcode.git" }, From 18fb3908ebf367197210fd970d4a10d9e4d84992 Mon Sep 17 00:00:00 2001 From: Fatme Date: Fri, 6 Jul 2018 09:54:33 +0300 Subject: [PATCH 13/69] Fix "Assignment to constant variable." error --- lib/pbxProject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index b4afce1..255f652 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -1721,7 +1721,7 @@ function searchPathForFile(file, proj) { } if (typeof file === 'string') { - const relativeFilePath = file; + let relativeFilePath = file; if ($path.isAbsolute(file)) { const srcRoot = $path.dirname($path.dirname(proj.filepath)); From e2a7eee517856185c14af3e923deed6598d4c5db Mon Sep 17 00:00:00 2001 From: "Kristian D. Dimitrov" Date: Thu, 31 Jan 2019 14:27:43 +0200 Subject: [PATCH 14/69] fix: unit tests --- lib/pbxProject.js | 32 +++++++++++++++++++--------- test/BuildSettings.js | 2 +- test/FrameworkSearchPaths.js | 2 +- test/HeaderSearchPaths.js | 2 +- test/LibrarySearchPaths.js | 2 +- test/OtherLinkerFlags.js | 2 +- test/addFramework.js | 4 ++-- test/addHeaderFile.js | 6 +++--- test/addRemovePbxGroup.js | 1 - test/addResourceFile.js | 6 +++--- test/addSourceFile.js | 6 +++--- test/addStaticLibrary.js | 6 +++--- test/addToPbxFileReferenceSection.js | 6 +++--- test/dataModelDocument.js | 2 +- test/group.js | 2 +- test/multipleTargets.js | 2 +- test/pbxFile.js | 2 +- test/pbxProject.js | 15 ++++++++----- test/removeFramework.js | 2 +- test/removeHeaderFile.js | 6 +++--- test/removeResourceFile.js | 4 ++-- test/removeSourceFile.js | 3 ++- test/xcode5searchPaths.js | 2 +- 23 files changed, 67 insertions(+), 50 deletions(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 255f652..deed2d0 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -510,7 +510,7 @@ pbxProject.prototype.findMainPbxGroup = function () { } pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceTree, opt) { - + opt = opt || {}; var oldGroup = this.pbxGroupByName(name); if (oldGroup) { this.removePbxGroup(name, path); @@ -523,6 +523,7 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT isa: 'PBXGroup', children: [], name: name, + path: path, sourceTree: sourceTree ? sourceTree : '""' },//path is mandatory only for the main group fileReferenceSection = this.pbxFileReferenceSection(), @@ -551,7 +552,7 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT var srcRootPath = $path.dirname($path.dirname(this.filepath)); var file = new pbxFile($path.relative(srcRootPath, filePath)); - if (fs.lstatSync(filePath).isDirectory()) { + if (fs.existsSync(filePath) && fs.lstatSync(filePath).isDirectory()) { file.uuid = this.generateUuid(); file.fileRef = file.uuid; this.addToPbxFileReferenceSection(file); // PBXFileReference @@ -559,15 +560,21 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT pbxGroup.children.push(pbxGroupChild(file)); var files = fs.readdirSync(filePath).map(p => $path.join(filePath, p)); this.addPbxGroup(files, $path.basename(filePath), filePath, null, {uuid: file.uuid}); - }else if (isSourceOrHeaderFileType(file.lastType)) { + } else if (isSourceOrHeaderFileType(file.lastKnownFileType)) { file.uuid = this.generateUuid(); file.fileRef = this.generateUuid(); this.addToPbxFileReferenceSection(file); // PBXFileReference this.addToPbxBuildFileSection(file); // PBXBuildFile - if (!isHeaderFileType(file.lastType)) { + if (!isHeaderFileType(file.lastKnownFileType)) { this.addToPbxSourcesBuildPhase(file); } pbxGroup.children.push(pbxGroupChild(file)); + } else { + file.uuid = this.generateUuid(); + file.fileRef = this.generateUuid(); + this.addToPbxFileReferenceSection(file); // PBXFileReference + this.addToPbxBuildFileSection(file); + pbxGroup.children.push(pbxGroupChild(file)); } } @@ -594,6 +601,8 @@ pbxProject.prototype.removePbxGroup = function(groupName, path) { if (!group) { return; } + + path = path || $path.dirname(this.filepath); var children = group.children; @@ -607,10 +616,13 @@ pbxProject.prototype.removePbxGroup = function(groupName, path) { this.removeFromPbxSourcesBuildPhase(file); } - var mainGroupChildren = this.findMainPbxGroup().children, i; - for(i in mainGroupChildren) { - if (mainGroupChildren[i].comment == name) { - mainGroupChildren.splice(i, 1); + var mainGroup = this.findMainPbxGroup(); + if(mainGroup) { + var mainGroupChildren = this.findMainPbxGroup().children, i; + for(i in mainGroupChildren) { + if (mainGroupChildren[i].comment == name) { + mainGroupChildren.splice(i, 1); + } } } @@ -1592,12 +1604,12 @@ function pbxFileReferenceObj(file) { includeInIndex: file.includeInIndex }; - if(fileObject.name.indexOf("\"") !== -1) { + if(fileObject.name && fileObject.name.indexOf("\"") !== -1) { fileObject.name = fileObject.name.replace(/\"/g, "\\\""); fileObject.path = fileObject.path.replace(/\"/g, "\\\""); } - if(!file.basename.match(NO_SPECIAL_SYMBOLS)) { + if(file.basename && !file.basename.match(NO_SPECIAL_SYMBOLS)) { fileObject.name = "\"" + fileObject.name + "\""; } diff --git a/test/BuildSettings.js b/test/BuildSettings.js index 213f575..698ce06 100644 --- a/test/BuildSettings.js +++ b/test/BuildSettings.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, proj = new pbx('.'); function cleanHash() { diff --git a/test/FrameworkSearchPaths.js b/test/FrameworkSearchPaths.js index b709f3a..d6fb0ce 100644 --- a/test/FrameworkSearchPaths.js +++ b/test/FrameworkSearchPaths.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, proj = new pbx('.'); var pbxFile = { diff --git a/test/HeaderSearchPaths.js b/test/HeaderSearchPaths.js index 998fd8b..1377384 100644 --- a/test/HeaderSearchPaths.js +++ b/test/HeaderSearchPaths.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, proj = new pbx('.'); function cleanHash() { diff --git a/test/LibrarySearchPaths.js b/test/LibrarySearchPaths.js index 6788e10..5b1461b 100644 --- a/test/LibrarySearchPaths.js +++ b/test/LibrarySearchPaths.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, proj = new pbx('.'); function cleanHash() { diff --git a/test/OtherLinkerFlags.js b/test/OtherLinkerFlags.js index de59f4c..f77ea8f 100644 --- a/test/OtherLinkerFlags.js +++ b/test/OtherLinkerFlags.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, proj = new pbx('.'); function cleanHash() { diff --git a/test/addFramework.js b/test/addFramework.js index c3c3200..11358ef 100644 --- a/test/addFramework.js +++ b/test/addFramework.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, proj = new pbx('.'); function cleanHash() { @@ -98,7 +98,7 @@ exports.addFramework = { test.equal(fileRefEntry.isa, 'PBXFileReference'); test.equal(fileRefEntry.lastKnownFileType, 'compiled.mach-o.dylib'); - test.equal(fileRefEntry.name, '"libsqlite3.dylib"'); + test.equal(fileRefEntry.name, 'libsqlite3.dylib'); test.equal(fileRefEntry.path, '"usr/lib/libsqlite3.dylib"'); test.equal(fileRefEntry.sourceTree, 'SDKROOT'); diff --git a/test/addHeaderFile.js b/test/addHeaderFile.js index f9bd71a..f96a736 100644 --- a/test/addHeaderFile.js +++ b/test/addHeaderFile.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, proj = new pbx('.'); function cleanHash() { @@ -70,8 +70,8 @@ exports.addHeaderFile = { test.equal(fileRefEntry.isa, 'PBXFileReference'); test.equal(fileRefEntry.fileEncoding, 4); test.equal(fileRefEntry.lastKnownFileType, 'sourcecode.c.h'); - test.equal(fileRefEntry.name, '"file.h"'); - test.equal(fileRefEntry.path, '"file.h"'); + test.equal(fileRefEntry.name, 'file.h'); + test.equal(fileRefEntry.path, 'file.h'); test.equal(fileRefEntry.sourceTree, '""'); test.done(); diff --git a/test/addRemovePbxGroup.js b/test/addRemovePbxGroup.js index 8212f91..74006da 100644 --- a/test/addRemovePbxGroup.js +++ b/test/addRemovePbxGroup.js @@ -169,7 +169,6 @@ exports.addRemovePbxGroup = { proj.removePbxGroup(groupName); var pbxGroupInPbx = proj.pbxGroupByName(groupName); - console.log(pbxGroupInPbx); test.ok(!pbxGroupInPbx); test.done() diff --git a/test/addResourceFile.js b/test/addResourceFile.js index 36afdb2..04b6013 100644 --- a/test/addResourceFile.js +++ b/test/addResourceFile.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, proj = new pbx('.'); function cleanHash() { @@ -108,7 +108,7 @@ exports.addResourceFile = { test.equal(fileRefEntry.isa, 'PBXFileReference'); test.equal(fileRefEntry.fileEncoding, undefined); test.equal(fileRefEntry.lastKnownFileType, 'wrapper.plug-in'); - test.equal(fileRefEntry.name, '"assets.bundle"'); + test.equal(fileRefEntry.name, 'assets.bundle'); test.equal(fileRefEntry.path, '"Resources/assets.bundle"'); test.equal(fileRefEntry.sourceTree, '""'); @@ -169,7 +169,7 @@ exports.addResourceFile = { test.equal(fileRefEntry.isa, 'PBXFileReference'); test.equal(fileRefEntry.fileEncoding, undefined); test.equal(fileRefEntry.lastKnownFileType, 'wrapper.plug-in'); - test.equal(fileRefEntry.name, '"assets.bundle"'); + test.equal(fileRefEntry.name, 'assets.bundle'); test.equal(fileRefEntry.path, '"Plugins/assets.bundle"'); test.equal(fileRefEntry.sourceTree, '""'); test.done(); diff --git a/test/addSourceFile.js b/test/addSourceFile.js index d614d62..fd5352b 100644 --- a/test/addSourceFile.js +++ b/test/addSourceFile.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, proj = new pbx('.'); function cleanHash() { @@ -106,8 +106,8 @@ exports.addSourceFile = { test.equal(fileRefEntry.isa, 'PBXFileReference'); test.equal(fileRefEntry.fileEncoding, 4); test.equal(fileRefEntry.lastKnownFileType, 'sourcecode.c.objc'); - test.equal(fileRefEntry.name, '"file.m"'); - test.equal(fileRefEntry.path, '"file.m"'); + test.equal(fileRefEntry.name, 'file.m'); + test.equal(fileRefEntry.path, 'file.m'); test.equal(fileRefEntry.sourceTree, '""'); test.done(); diff --git a/test/addStaticLibrary.js b/test/addStaticLibrary.js index d1b0ec6..9b48546 100644 --- a/test/addStaticLibrary.js +++ b/test/addStaticLibrary.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, proj = new pbx('.'); function cleanHash() { @@ -140,8 +140,8 @@ exports.addStaticLibrary = { test.equal(fileRefEntry.isa, 'PBXFileReference'); test.equal(fileRefEntry.lastKnownFileType, 'archive.ar'); - test.equal(fileRefEntry.name, '"libGoogleAnalytics.a"'); - test.equal(fileRefEntry.path, '"libGoogleAnalytics.a"'); + test.equal(fileRefEntry.name, 'libGoogleAnalytics.a'); + test.equal(fileRefEntry.path, 'libGoogleAnalytics.a'); test.equal(fileRefEntry.sourceTree, '""'); test.done(); diff --git a/test/addToPbxFileReferenceSection.js b/test/addToPbxFileReferenceSection.js index d69abbc..da5f440 100644 --- a/test/addToPbxFileReferenceSection.js +++ b/test/addToPbxFileReferenceSection.js @@ -18,7 +18,7 @@ var jsonProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(jsonProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, myProj = new pbx('.'); function cleanHash() { @@ -39,8 +39,8 @@ exports['addToPbxFileReferenceSection function'] = { test.equal(myProj.pbxFileReferenceSection()[file.fileRef].isa, 'PBXFileReference'); test.equal(myProj.pbxFileReferenceSection()[file.fileRef].lastKnownFileType, 'sourcecode.c.objc'); - test.equal(myProj.pbxFileReferenceSection()[file.fileRef].name, '"file.m"'); - test.equal(myProj.pbxFileReferenceSection()[file.fileRef].path, '"file.m"'); + test.equal(myProj.pbxFileReferenceSection()[file.fileRef].name, 'file.m'); + test.equal(myProj.pbxFileReferenceSection()[file.fileRef].path, 'file.m'); test.equal(myProj.pbxFileReferenceSection()[file.fileRef].sourceTree, '""'); test.equal(myProj.pbxFileReferenceSection()[file.fileRef].fileEncoding, 4); test.equal(myProj.pbxFileReferenceSection()[file.fileRef + "_comment"], 'file.m'); diff --git a/test/dataModelDocument.js b/test/dataModelDocument.js index 76477ed..c809d62 100644 --- a/test/dataModelDocument.js +++ b/test/dataModelDocument.js @@ -19,7 +19,7 @@ var jsonProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(jsonProject), path = require('path'), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, proj = new pbx('.'), singleDataModelFilePath = __dirname + '/fixtures/single-data-model.xcdatamodeld', multipleDataModelFilePath = __dirname + '/fixtures/multiple-data-model.xcdatamodeld'; diff --git a/test/group.js b/test/group.js index af2454e..5072aa1 100644 --- a/test/group.js +++ b/test/group.js @@ -16,7 +16,7 @@ */ var pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, project, projectHash; diff --git a/test/multipleTargets.js b/test/multipleTargets.js index dbb945f..dc4c419 100644 --- a/test/multipleTargets.js +++ b/test/multipleTargets.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/multiple-targets') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, proj = new pbx('.'); function cleanHash() { diff --git a/test/pbxFile.js b/test/pbxFile.js index 4f0d1a2..f096120 100644 --- a/test/pbxFile.js +++ b/test/pbxFile.js @@ -15,7 +15,7 @@ under the License. */ -var pbxFile = require('../lib/pbxFile'); +var pbxFile = require('../lib/pbxFile').pbxFile; exports['lastKnownFileType'] = { 'should detect that a .m path means sourcecode.c.objc': function (test) { diff --git a/test/pbxProject.js b/test/pbxProject.js index 176f836..e846294 100644 --- a/test/pbxProject.js +++ b/test/pbxProject.js @@ -18,9 +18,14 @@ var pbx = require('../lib/pbxProject'), buildConfig = require('./fixtures/buildFiles'), jsonProject = require('./fixtures/full-project'), + fullProjectStr = JSON.stringify(jsonProject), fs = require('fs'), project; + function getCleanHash() { + return JSON.parse(fullProjectStr); + } + exports['creation'] = { 'should create a pbxProject with the new operator': function (test) { var myProj = new pbx('test/parser/projects/hash.pbxproj'); @@ -332,7 +337,7 @@ exports['hasFile'] = { exports['addToPbxFileReferenceSection'] = { 'should not quote name when no special characters present in basename': function (test) { var newProj = new pbx('.'); - newProj.hash = jsonProject, + newProj.hash = getCleanHash(), file = { uuid: newProj.generateUuid(), fileRef: newProj.generateUuid(), @@ -351,7 +356,7 @@ exports['addToPbxFileReferenceSection'] = { }, 'should quote name when special characters present in basename': function (test) { var newProj = new pbx('.'); - newProj.hash = jsonProject, + newProj.hash = getCleanHash(), file = { uuid: newProj.generateUuid(), fileRef: newProj.generateUuid(), @@ -370,7 +375,7 @@ exports['addToPbxFileReferenceSection'] = { }, 'should not quote path when no special characters present in path': function (test) { var newProj = new pbx('.'); - newProj.hash = jsonProject, + newProj.hash = getCleanHash(), file = { uuid: newProj.generateUuid(), fileRef: newProj.generateUuid(), @@ -389,7 +394,7 @@ exports['addToPbxFileReferenceSection'] = { }, 'should quote path when special characters present in path': function (test) { var newProj = new pbx('.'); - newProj.hash = jsonProject, + newProj.hash = getCleanHash(), file = { uuid: newProj.generateUuid(), fileRef: newProj.generateUuid(), @@ -408,7 +413,7 @@ exports['addToPbxFileReferenceSection'] = { }, 'should quote path and name when special characters present in path and basename': function (test) { var newProj = new pbx('.'); - newProj.hash = jsonProject, + newProj.hash = getCleanHash(), file = { uuid: newProj.generateUuid(), fileRef: newProj.generateUuid(), diff --git a/test/removeFramework.js b/test/removeFramework.js index 20cdbde..15312d4 100644 --- a/test/removeFramework.js +++ b/test/removeFramework.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project'), fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, proj = new pbx('.'); function cleanHash() { diff --git a/test/removeHeaderFile.js b/test/removeHeaderFile.js index acda161..973533a 100644 --- a/test/removeHeaderFile.js +++ b/test/removeHeaderFile.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, proj = new pbx('.'); function cleanHash() { @@ -94,8 +94,8 @@ exports.removeHeaderFile = { test.equal(fileRefEntry.isa, 'PBXFileReference'); test.equal(fileRefEntry.fileEncoding, 4); test.equal(fileRefEntry.lastKnownFileType, 'sourcecode.c.h'); - test.equal(fileRefEntry.name, '"file.h"'); - test.equal(fileRefEntry.path, '"file.h"'); + test.equal(fileRefEntry.name, 'file.h'); + test.equal(fileRefEntry.path, 'file.h'); test.equal(fileRefEntry.sourceTree, '""'); var deletedFile = proj.removeHeaderFile('Plugins/file.h'), diff --git a/test/removeResourceFile.js b/test/removeResourceFile.js index bda48f9..ca7bb94 100644 --- a/test/removeResourceFile.js +++ b/test/removeResourceFile.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, proj = new pbx('.'); function cleanHash() { @@ -158,7 +158,7 @@ exports.removeResourceFile = { test.equal(fileRefEntry.isa, 'PBXFileReference'); test.equal(fileRefEntry.fileEncoding, undefined); test.equal(fileRefEntry.lastKnownFileType, 'wrapper.plug-in'); - test.equal(fileRefEntry.name, '"assets.bundle"'); + test.equal(fileRefEntry.name, 'assets.bundle'); test.equal(fileRefEntry.path, '"Resources/assets.bundle"'); test.equal(fileRefEntry.sourceTree, '""'); diff --git a/test/removeSourceFile.js b/test/removeSourceFile.js index de7895e..df9f2e7 100644 --- a/test/removeSourceFile.js +++ b/test/removeSourceFile.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, proj = new pbx('.'); function cleanHash() { @@ -83,6 +83,7 @@ exports.removeSourceFile = { test.done(); }, 'should remove 2 fields from the PBXFileReference section': function (test) { + debugger proj.addSourceFile('file.m'); var newFile = proj.removeSourceFile('file.m'), fileRefSection = proj.pbxFileReferenceSection(), diff --git a/test/xcode5searchPaths.js b/test/xcode5searchPaths.js index 7cdf46c..61014cb 100644 --- a/test/xcode5searchPaths.js +++ b/test/xcode5searchPaths.js @@ -18,7 +18,7 @@ var xcode5proj = require('./fixtures/library-search-paths') xcode5projStr = JSON.stringify(xcode5proj), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile'), + pbxFile = require('../lib/pbxFile').pbxFile, proj = new pbx('.'), libPoop = { path: 'some/path/poop.a' }; From d607e87e1cef91dbce0e6f3f06a0e076aeaa16d6 Mon Sep 17 00:00:00 2001 From: "Kristian D. Dimitrov" Date: Wed, 27 Feb 2019 17:54:41 +0200 Subject: [PATCH 15/69] fix: add and remove pbxGroup --- lib/pbxProject.js | 12 ++++++++---- .../with_omit_empty_values_disabled_expected.pbxproj | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index deed2d0..d854289 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -523,12 +523,16 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT isa: 'PBXGroup', children: [], name: name, - path: path, sourceTree: sourceTree ? sourceTree : '""' - },//path is mandatory only for the main group + }, fileReferenceSection = this.pbxFileReferenceSection(), filePathToReference = {}; + //path is mandatory only for the main group + if(!opt.filesRelativeToProject) { + pbxGroup.path = path; + } + for (var key in fileReferenceSection) { // only look for comments if (!COMMENT_KEY.test(key)) continue; @@ -602,7 +606,7 @@ pbxProject.prototype.removePbxGroup = function(groupName, path) { return; } - path = path || $path.dirname(this.filepath); + path = path || ""; var children = group.children; @@ -620,7 +624,7 @@ pbxProject.prototype.removePbxGroup = function(groupName, path) { if(mainGroup) { var mainGroupChildren = this.findMainPbxGroup().children, i; for(i in mainGroupChildren) { - if (mainGroupChildren[i].comment == name) { + if (mainGroupChildren[i].comment == groupName) { mainGroupChildren.splice(i, 1); } } diff --git a/test/parser/projects/expected/with_omit_empty_values_disabled_expected.pbxproj b/test/parser/projects/expected/with_omit_empty_values_disabled_expected.pbxproj index da46b23..b143630 100644 --- a/test/parser/projects/expected/with_omit_empty_values_disabled_expected.pbxproj +++ b/test/parser/projects/expected/with_omit_empty_values_disabled_expected.pbxproj @@ -260,8 +260,8 @@ children = ( ); name = CustomGroup; - path = undefined; sourceTree = ""; + path = undefined; }; /* End PBXGroup section */ From f85f635fa5579e21efb31d06d102d3cff9d4398c Mon Sep 17 00:00:00 2001 From: "Kristian D. Dimitrov" Date: Thu, 28 Feb 2019 16:49:44 +0200 Subject: [PATCH 16/69] fix: addPbxGroup nested folders with relative path --- lib/pbxProject.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index d854289..793c01c 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -555,7 +555,8 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT } var srcRootPath = $path.dirname($path.dirname(this.filepath)); - var file = new pbxFile($path.relative(srcRootPath, filePath)); + var relativePath = $path.relative(srcRootPath, filePath); + var file = new pbxFile(opt.filesRelativeToProject ? relativePath : filePath); if (fs.existsSync(filePath) && fs.lstatSync(filePath).isDirectory()) { file.uuid = this.generateUuid(); file.fileRef = file.uuid; @@ -563,7 +564,7 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT this.addToPbxBuildFileSection(file); pbxGroup.children.push(pbxGroupChild(file)); var files = fs.readdirSync(filePath).map(p => $path.join(filePath, p)); - this.addPbxGroup(files, $path.basename(filePath), filePath, null, {uuid: file.uuid}); + this.addPbxGroup(files, $path.basename(filePath), filePath, null, {uuid: file.uuid, filesRelativeToProject: opt.filesRelativeToProject}); } else if (isSourceOrHeaderFileType(file.lastKnownFileType)) { file.uuid = this.generateUuid(); file.fileRef = this.generateUuid(); From 89029f9820379f03ed971b66beaf14251855aa6f Mon Sep 17 00:00:00 2001 From: "Kristian D. Dimitrov" Date: Mon, 18 Mar 2019 18:28:25 +0200 Subject: [PATCH 17/69] chore: update readme --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 814a221..c494f5d 100644 --- a/README.md +++ b/README.md @@ -21,14 +21,16 @@ # cordova-node-xcode -[![NPM](https://nodei.co/npm/xcode.png?compact=true)](https://nodei.co/npm/xcode/) -[![Build Status](https://travis-ci.org/apache/cordova-node-xcode.svg?branch=master)](https://travis-ci.org/apache/cordova-node-xcode) + +[![Build Status](https://travis-ci.org/NativeScript/nativescript-dev-xcode.svg?branch=master)](https://travis-ci.org/apache/cordova-node-xcode) Parser utility for xcodeproj project files Allows you to edit xcodeproject files and write them back out. -based on donated code from [alunny / node-xcode](https://github.com/alunny/node-xcode) +Forked from: [apache/cordova-node-xcode](https://github.com/apache/cordova-node-xcode) ## Example From 4db603acf4656e2aa5bca8b1ef91686a58dc02d3 Mon Sep 17 00:00:00 2001 From: "Kristian D. Dimitrov" Date: Mon, 18 Mar 2019 14:08:17 +0200 Subject: [PATCH 18/69] chore: update package json --- package.json | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index 2398b84..4d589aa 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { - "author": "Apache Software Foundation", - "name": "xcode", + "author": "Telerik ", + "name": "nativescript-dev-xcode", "description": "parser for xcodeproj/project.pbxproj files", "main":"index.js", - "version": "1.5.2-NativeScript", + "version": "0.1.0", "repository": { - "url": "https://github.com/apache/cordova-node-xcode.git" + "url": "https://github.com/NativeScript/nativescript-dev-xcode.git" }, "engines": { "node": ">=6.0.0" @@ -22,27 +22,5 @@ "pegjs": "node_modules/.bin/pegjs lib/parser/pbxproj.pegjs", "test": "node_modules/.bin/nodeunit test/parser test" }, - "license": "Apache-2.0", - "contributors": [ - { - "name": "Andrew Lunny", - "email": "alunny@gmail.com" - }, - { - "name": "Anis Kadri" - }, - { - "name": "Mike Reinstein" - }, - { - "name": "Filip Maj" - }, - { - "name": "Brett Rudd", - "email": "goya@apache.org" - }, - { - "name": "Bob Easterday" - } - ] + "license": "Apache-2.0" } From 5cec2fe9a85f568555980f0d87ef64d98bfb1985 Mon Sep 17 00:00:00 2001 From: "Kristian D. Dimitrov" Date: Thu, 7 Feb 2019 15:17:29 +0200 Subject: [PATCH 19/69] improve extensions handling --- lib/pbxFile.js | 7 ++++++- lib/pbxProject.js | 26 +++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/lib/pbxFile.js b/lib/pbxFile.js index fa0fb68..703a91f 100644 --- a/lib/pbxFile.js +++ b/lib/pbxFile.js @@ -109,6 +109,10 @@ function isHeaderFileType(fileType) { return fileType.endsWith(HEADER_FILE_TYPE_SUFFIX); } +function isResource(group) { + return group === "Resources"; +} + function unquoted(text){ return text == null ? '' : text.replace (/(^")|("$)/g, '') } @@ -260,5 +264,6 @@ function pbxFile(filepath, opt) { module.exports = { pbxFile: pbxFile, isSourceOrHeaderFileType, - isHeaderFileType + isHeaderFileType, + isResource } diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 793c01c..3cda9ba 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -25,6 +25,7 @@ var util = require('util'), pbxFile = require('./pbxFile').pbxFile, isSourceOrHeaderFileType = require('./pbxFile').isSourceOrHeaderFileType, isHeaderFileType = require('./pbxFile').isHeaderFileType, + isResource = require('./pbxFile').isResource, fs = require('fs'), parser = require('./parser/pbxproj'), plist = require('simple-plist'), @@ -557,6 +558,11 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT var srcRootPath = $path.dirname($path.dirname(this.filepath)); var relativePath = $path.relative(srcRootPath, filePath); var file = new pbxFile(opt.filesRelativeToProject ? relativePath : filePath); + + if(opt.target) { + file.target = opt.target; + } + if (fs.existsSync(filePath) && fs.lstatSync(filePath).isDirectory()) { file.uuid = this.generateUuid(); file.fileRef = file.uuid; @@ -564,7 +570,7 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT this.addToPbxBuildFileSection(file); pbxGroup.children.push(pbxGroupChild(file)); var files = fs.readdirSync(filePath).map(p => $path.join(filePath, p)); - this.addPbxGroup(files, $path.basename(filePath), filePath, null, {uuid: file.uuid, filesRelativeToProject: opt.filesRelativeToProject}); + this.addPbxGroup(files, $path.basename(filePath), filePath, null, {uuid: file.uuid, filesRelativeToProject: opt.filesRelativeToProject, target: opt.target}); } else if (isSourceOrHeaderFileType(file.lastKnownFileType)) { file.uuid = this.generateUuid(); file.fileRef = this.generateUuid(); @@ -574,6 +580,12 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT this.addToPbxSourcesBuildPhase(file); } pbxGroup.children.push(pbxGroupChild(file)); + } else if(isResource(file.group)) { + file.uuid = this.generateUuid(); + file.fileRef = this.generateUuid(); + this.addToPbxFileReferenceSection(file); // PBXFileReference + this.addToPbxResourcesBuildPhase(file) + pbxGroup.children.push(pbxGroupChild(file)); } else { file.uuid = this.generateUuid(); file.fileRef = this.generateUuid(); @@ -922,6 +934,14 @@ pbxProject.prototype.addTargetDependency = function(target, dependencyTargets) { pbxTargetDependencySection = this.hash.project.objects[pbxTargetDependency], pbxContainerItemProxySection = this.hash.project.objects[pbxContainerItemProxy]; + if(!pbxTargetDependencySection){ + pbxTargetDependencySection = this.hash.project.objects[pbxTargetDependency] = {}; + } + + if(!pbxContainerItemProxySection){ + pbxContainerItemProxySection = this.hash.project.objects[pbxContainerItemProxy] = {}; + } + for (var index = 0; index < dependencyTargets.length; index++) { var dependencyTargetUuid = dependencyTargets[index], dependencyTargetCommentKey = f("%s_comment", dependencyTargetUuid), @@ -934,7 +954,7 @@ pbxProject.prototype.addTargetDependency = function(target, dependencyTargets) { containerPortal: this.hash.project['rootObject'], containerPortal_comment: this.hash.project['rootObject_comment'], proxyType: 1, - remoteGlobalIDString: dependencyTargetUuid, + remoteGlobalIDString: dependencyTargetUuid, remoteInfo: nativeTargets[dependencyTargetUuid].name }, targetDependency = { @@ -1158,8 +1178,8 @@ pbxProject.prototype.buildPhase = function(group, target) { var buildPhase = buildPhases[i]; if (buildPhase.comment==group) return buildPhase.value + "_comment"; - } } +} pbxProject.prototype.buildPhaseObject = function(name, group, target) { var section = this.hash.project.objects[name], From 983174ec512a62674f9d62facfcfa34f5930e949 Mon Sep 17 00:00:00 2001 From: "Kristian D. Dimitrov" Date: Wed, 13 Feb 2019 12:22:33 +0200 Subject: [PATCH 20/69] add localization in addPbxGroup --- lib/pbxProject.js | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 3cda9ba..a59f552 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -566,11 +566,22 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT if (fs.existsSync(filePath) && fs.lstatSync(filePath).isDirectory()) { file.uuid = this.generateUuid(); file.fileRef = file.uuid; - this.addToPbxFileReferenceSection(file); // PBXFileReference - this.addToPbxBuildFileSection(file); - pbxGroup.children.push(pbxGroupChild(file)); var files = fs.readdirSync(filePath).map(p => $path.join(filePath, p)); - this.addPbxGroup(files, $path.basename(filePath), filePath, null, {uuid: file.uuid, filesRelativeToProject: opt.filesRelativeToProject, target: opt.target}); + if($path.extname(filePath) === ".lproj") { + for (var i = 0; i < files.length; i++) { + var variantGroup = this.addLocalizationVariantGroup($path.basename(files[i]), { target: opt.target, skipAddToResourcesGroup: true }); + var refFile = new pbxFile($path.relative(srcRootPath, files[i]), {basename: $path.parse(file.basename).name}); + refFile.fileRef = this.generateUuid(); + this.addToPbxFileReferenceSection(refFile); + this.addToPbxVariantGroup(refFile, variantGroup.fileRef); + pbxGroup.children.push(pbxGroupChild(variantGroup)); + } + } else { + this.addToPbxFileReferenceSection(file); // PBXFileReference + this.addToPbxBuildFileSection(file); + pbxGroup.children.push(pbxGroupChild(file)); + this.addPbxGroup(files, $path.basename(filePath), filePath, null, {uuid: file.uuid, filesRelativeToProject: opt.filesRelativeToProject, target: opt.target}); + } } else if (isSourceOrHeaderFileType(file.lastKnownFileType)) { file.uuid = this.generateUuid(); file.fileRef = this.generateUuid(); @@ -1026,7 +1037,7 @@ pbxProject.prototype.addBuildPhase = function(filePathsArray, buildPhaseType, co if (!fileReference) continue; - var pbxFileObj = new pbxFile(fileReference.path); + var pbxFileObj = new pbxFile(fileReference.path || ""); filePathToBuildFile[fileReference.path] = { uuid: buildFileKey, basename: pbxFileObj.basename, group: pbxFileObj.group }; } @@ -1202,13 +1213,13 @@ pbxProject.prototype.buildPhaseObject = function(name, group, target) { return null; } -pbxProject.prototype.addBuildProperty = function(prop, value, build_name) { +pbxProject.prototype.addBuildProperty = function(prop, value, build_name, productName) { var configurations = nonComments(this.pbxXCBuildConfigurationSection()), key, configuration; for (key in configurations){ configuration = configurations[key]; - if (!build_name || configuration.name === build_name){ + if ((!build_name || configuration.name === build_name) && (!productName || configuration.buildSettings.PRODUCT_NAME === productName || configuration.buildSettings.PRODUCT_NAME === `"${productName}"`)) { configuration.buildSettings[prop] = value; } } @@ -1515,7 +1526,7 @@ pbxProject.prototype.addTarget = function(name, type, subfolder) { isa: 'XCBuildConfiguration', buildSettings: { GCC_PREPROCESSOR_DEFINITIONS: ['"DEBUG=1"', '"$(inherited)"'], - INFOPLIST_FILE: '"' + $path.join(targetSubfolder, targetSubfolder + '-Info.plist' + '"'), + INFOPLIST_FILE: '"' + $path.join(targetSubfolder, 'Info.plist' + '"'), LD_RUNPATH_SEARCH_PATHS: '"$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"', PRODUCT_NAME: '"' + targetName + '"', SKIP_INSTALL: 'YES' @@ -1525,7 +1536,7 @@ pbxProject.prototype.addTarget = function(name, type, subfolder) { name: 'Release', isa: 'XCBuildConfiguration', buildSettings: { - INFOPLIST_FILE: '"' + $path.join(targetSubfolder, targetSubfolder + '-Info.plist' + '"'), + INFOPLIST_FILE: '"' + $path.join(targetSubfolder, 'Info.plist' + '"'), LD_RUNPATH_SEARCH_PATHS: '"$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"', PRODUCT_NAME: '"' + targetName + '"', SKIP_INSTALL: 'YES' @@ -2037,16 +2048,24 @@ pbxProject.prototype.findPBXVariantGroupKey = function(criteria) { return this.findPBXGroupKeyAndType(criteria, 'PBXVariantGroup'); } -pbxProject.prototype.addLocalizationVariantGroup = function(name) { +pbxProject.prototype.addLocalizationVariantGroup = function(name, ops) { + ops = ops || {}; var groupKey = this.pbxCreateVariantGroup(name); - var resourceGroupKey = this.findPBXGroupKey({name: 'Resources'}); - this.addToPbxGroup(groupKey, resourceGroupKey); + if(!ops.skipAddToResourcesGroup) { + var resourcesGroupKey = this.findPBXGroupKey({name: 'Resources'}); + this.addToPbxGroup(groupKey, resourcesGroupKey); + } var localizationVariantGroup = { uuid: this.generateUuid(), fileRef: groupKey, - basename: name + basename: name, + group: "Resources", + children: [] + } + if(ops.target) { + localizationVariantGroup.target = ops.target; } this.addToPbxBuildFileSection(localizationVariantGroup); // PBXBuildFile this.addToPbxResourcesBuildPhase(localizationVariantGroup); //PBXResourcesBuildPhase From 8e2ba688de539b21d93a18d6fd82ae378a600365 Mon Sep 17 00:00:00 2001 From: "Kristian D. Dimitrov" Date: Thu, 7 Mar 2019 19:52:10 +0200 Subject: [PATCH 21/69] feat: add removeTarget method --- lib/pbxProject.js | 183 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 178 insertions(+), 5 deletions(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index a59f552..5e3c495 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -487,14 +487,16 @@ pbxProject.prototype.removeFromPbxBuildFileSection = function(file) { for (uuid in this.pbxBuildFileSection()) { if (this.pbxBuildFileSection()[uuid].fileRef_comment == file.basename) { file.uuid = uuid; - delete this.pbxBuildFileSection()[uuid]; - - var commentKey = f("%s_comment", uuid); - delete this.pbxBuildFileSection()[commentKey]; + this.removeFromPbxBuildFileSectionByUuid(uuid); } } } +pbxProject.prototype.removeFromPbxBuildFileSectionByUuid = function(uuid) { + var buildSection = this.pbxBuildFileSection(); + removeItemAndCommentFromSectionByUuid(buildSection, uuid); +} + pbxProject.prototype.findMainPbxGroup = function () { var groups = this.hash.project.objects['PBXGroup']; var candidates = []; @@ -604,7 +606,6 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT this.addToPbxBuildFileSection(file); pbxGroup.children.push(pbxGroupChild(file)); } - } if (groups) { @@ -1599,9 +1600,181 @@ pbxProject.prototype.addTarget = function(name, type, subfolder) { // Return target on success return target; +}; + +pbxProject.prototype.removeTargetsByProductType = function(targetProductType) { + var nativeTargetsNonComments = nonComments(this.pbxNativeTargetSection()); + + for (var nativeTargetUuid in nativeTargetsNonComments) { + var target = nativeTargetsNonComments[nativeTargetUuid]; + if(target.productType === targetProductType || target.productType === `"${targetProductType}"`) { + this.removeTarget(target, nativeTargetUuid); + } + } +} + +pbxProject.prototype.removeTarget = function(target, targetKey) { + let files = []; + + // iterate all buildPhases and collect all files that should be removed + // remove the phase from the appropriate section + var buildPhases = target["buildPhases"]; + for (let i = 0; i < buildPhases.length; i++) { + var buildPhase = buildPhases[i]; + var sectionUuid = buildPhase.value; + var section = {}; //in case we don't recognise the section + if(buildPhase.comment === buildPhaseNameForIsa("PBXSourcesBuildPhase")){ + var section = this.hash.project.objects["PBXSourcesBuildPhase"]; + files = files.concat(section[sectionUuid].files); + } else if (buildPhase.comment === buildPhaseNameForIsa("PBXResourcesBuildPhase")) { + var section = this.hash.project.objects["PBXResourcesBuildPhase"]; + files = files.concat(section[sectionUuid].files); + } else if (buildPhase.comment === buildPhaseNameForIsa("PBXFrameworksBuildPhase")) { + var section = this.hash.project.objects["PBXFrameworksBuildPhase"]; + files = files.concat(section[sectionUuid].files); + } + + removeItemAndCommentFromSectionByUuid(section, sectionUuid); + } + + //remove files from all build phases from PBXBuildFile section + for (let k = 0; k < files.length; k++) { + const uuid = files[k].value; + this.removeFromPbxBuildFileSectionByUuid(uuid); + } + + //remove target from the project itself + var targets = this.pbxProjectSection()[this.getFirstProject()['uuid']]['targets'] + for (let l = 0; l < targets.length; l++) { + if(targets[l].value === targetKey){ + targets.splice(l,1); + } + } + + //remove target build configurations + //get configurationList object and get all configuration uuids + var buildConfigurationList = target["buildConfigurationList"]; + var pbxXCConfigurationListSection = this.pbxXCConfigurationList(); + var xcConfigurationList = pbxXCConfigurationListSection[buildConfigurationList] || {}; + var buildConfigurations = xcConfigurationList.buildConfigurations || []; + //remove all configurations from XCBuildConfiguration section + var pbxBuildConfigurationSection = this.pbxXCBuildConfigurationSection() + for (let m = 0; m < buildConfigurations.length; m++) { + const configuration = buildConfigurations[m]; + removeItemAndCommentFromSectionByUuid(pbxBuildConfigurationSection, configuration.value); + } + + //remove the XCConfigurationList from the section + removeItemAndCommentFromSectionByUuid(pbxXCConfigurationListSection, buildConfigurationList); + + //get target product information + var productUuid = ""; + + var productReferenceUuid = target.productReference; + var pbxBuildFileSection = this.pbxBuildFileSection(); + var pbxBuildFileSectionNoComments = nonComments(pbxBuildFileSection); + + // the productReference is the uuid from the PBXFileReference Section, but we need the one in PBXBuildFile section + // check the fileRef of all records until we find the product + for (uuid in pbxBuildFileSectionNoComments) { + if (this.pbxBuildFileSection()[uuid].fileRef == productReferenceUuid) { + productUuid = uuid; + } + } + + //remove copy phase + var pbxCopySection = this.hash.project.objects["PBXCopyFilesBuildPhase"]; + var noCommentsCopySection = nonComments(pbxCopySection); + for (var copyPhaseId in noCommentsCopySection) { + var copyPhase = noCommentsCopySection[copyPhaseId]; + if(copyPhase.files) { + + //check if the product of the target is part of this copy phase files + for (let p = 0; p < copyPhase.files.length; p++) { + const copyFile = copyPhase.files[p]; + if(copyFile.value === productUuid) { + //if this is the only file in the copy phase - delete the whole phase and remove it from all targets + if(copyPhase.files.length === 1) { + var nativeTargetsnoComments = nonComments(this.pbxNativeTargetSection()); + for (var nativeTargetUuid in nativeTargetsnoComments) { + const nativeTarget = nativeTargetsnoComments[nativeTargetUuid]; + for (var phaseIndex in nativeTarget.buildPhases) { + if (nativeTarget.buildPhases[phaseIndex].value == copyPhaseId) { + //remove copy build phase from containing target + nativeTarget.buildPhases.splice(phaseIndex, 1); + break; + } + } + } + + //remove from copySection + removeItemAndCommentFromSectionByUuid(pbxCopySection, copyPhaseId); + } else { + //if there are other files in the copy phase, just remove the product + copyPhase.files(p, 1); + } + break; + } + } + } + } + + //remove the product from the PBXBuildFile section + removeItemAndCommentFromSectionByUuid(pbxBuildFileSection, productUuid); + + + //remove the product from the Products PBXGroup + var fileReferenceSection = this.pbxFileReferenceSection(); + var productReference = fileReferenceSection[productReferenceUuid]; + var productFile = new pbxFile(productReference.path); + productFile.fileRef = productReferenceUuid; + productFile.uuid = productReferenceUuid; + this.removeFromProductsPbxGroup(productFile); + + //remove the product from the PBXFileReference section + removeItemAndCommentFromSectionByUuid(fileReferenceSection, productReferenceUuid); + + + //find all PBXTargetDependency that refer the target and remove them with the PBXContainerItemProxy + var pbxTargetDependency = 'PBXTargetDependency'; + var pbxContainerItemProxy = 'PBXContainerItemProxy'; + var pbxTargetDependencySection = this.hash.project.objects[pbxTargetDependency]; + var pbxTargetDependencySectionNoComments = nonComments(pbxTargetDependencySection); + var pbxContainerItemProxySection = this.hash.project.objects[pbxContainerItemProxy]; + + for(var targetDependencyUuid in pbxTargetDependencySectionNoComments) { + targetDependency = pbxTargetDependencySectionNoComments[targetDependencyUuid]; + if(targetDependency.target === targetKey) { + //remove the PBXContainerItemProxy + removeItemAndCommentFromSectionByUuid(pbxContainerItemProxySection, targetDependency.targetProxy); + //remove the PBXTargetDependency from dependencies from all targets + for (var nativeTargetUuid in nativeTargetsnoComments) { + const nativeTarget = nativeTargetsnoComments[nativeTargetUuid]; + for (var dependencyIndex in nativeTarget.dependencies) { + if (nativeTarget.dependencies[dependencyIndex].value == targetDependencyUuid) { + nativeTarget.dependencies.splice(dependencyIndex, 1); + } + } + } + //remove the PBXTargetDependency + removeItemAndCommentFromSectionByUuid(pbxTargetDependencySection, targetDependencyUuid); + } + } + + //remove the target from PBXNativeTarget section + var nativeTargets = this.pbxNativeTargetSection(); + removeItemAndCommentFromSectionByUuid(nativeTargets, nativeTargetUuid); + + this.removePbxGroup(unquote(target.name)); }; +function removeItemAndCommentFromSectionByUuid(section, uuid) { + var commentKey = f("%s_comment", uuid) + delete section[commentKey]; + delete section[uuid]; +} + // helper recursive prop search+replace function propReplace(obj, prop, value) { var o = {}; From 98a8bd9d8549d8c215ad63d8bad18308c8b4d064 Mon Sep 17 00:00:00 2001 From: "Kristian D. Dimitrov" Date: Fri, 8 Mar 2019 18:05:34 +0200 Subject: [PATCH 22/69] fix: uuid module overwritten --- lib/pbxProject.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 5e3c495..92f4020 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -19,7 +19,7 @@ var util = require('util'), f = util.format, EventEmitter = require('events').EventEmitter, $path = require('path'), - uuid = require('uuid'), + $uuid = require('uuid'), fork = require('child_process').fork, pbxWriter = require('./pbxWriter'), pbxFile = require('./pbxFile').pbxFile, @@ -91,7 +91,7 @@ pbxProject.prototype.allUuids = function() { } pbxProject.prototype.generateUuid = function() { - var id = uuid.v4() + var id = $uuid.v4() .replace(/-/g, '') .substr(0, 24) .toUpperCase() @@ -482,19 +482,19 @@ pbxProject.prototype.addToPbxBuildFileSection = function(file) { } pbxProject.prototype.removeFromPbxBuildFileSection = function(file) { - var uuid; + var fileUuid; - for (uuid in this.pbxBuildFileSection()) { - if (this.pbxBuildFileSection()[uuid].fileRef_comment == file.basename) { - file.uuid = uuid; - this.removeFromPbxBuildFileSectionByUuid(uuid); + for (fileUuid in this.pbxBuildFileSection()) { + if (this.pbxBuildFileSection()[fileUuid].fileRef_comment == file.basename) { + file.uuid = fileUuid; + this.removeFromPbxBuildFileSectionByUuid(fileUuid); } } } -pbxProject.prototype.removeFromPbxBuildFileSectionByUuid = function(uuid) { +pbxProject.prototype.removeFromPbxBuildFileSectionByUuid = function(itemUuid) { var buildSection = this.pbxBuildFileSection(); - removeItemAndCommentFromSectionByUuid(buildSection, uuid); + removeItemAndCommentFromSectionByUuid(buildSection, itemUuid); } pbxProject.prototype.findMainPbxGroup = function () { @@ -1639,8 +1639,8 @@ pbxProject.prototype.removeTarget = function(target, targetKey) { //remove files from all build phases from PBXBuildFile section for (let k = 0; k < files.length; k++) { - const uuid = files[k].value; - this.removeFromPbxBuildFileSectionByUuid(uuid); + const fileUuid = files[k].value; + this.removeFromPbxBuildFileSectionByUuid(fileUuid); } //remove target from the project itself @@ -1712,7 +1712,7 @@ pbxProject.prototype.removeTarget = function(target, targetKey) { removeItemAndCommentFromSectionByUuid(pbxCopySection, copyPhaseId); } else { //if there are other files in the copy phase, just remove the product - copyPhase.files(p, 1); + copyPhase.files.splice(p, 1); } break; } @@ -1769,10 +1769,10 @@ pbxProject.prototype.removeTarget = function(target, targetKey) { this.removePbxGroup(unquote(target.name)); }; -function removeItemAndCommentFromSectionByUuid(section, uuid) { - var commentKey = f("%s_comment", uuid) +function removeItemAndCommentFromSectionByUuid(section, itemUuid) { + var commentKey = f("%s_comment", itemUuid) delete section[commentKey]; - delete section[uuid]; + delete section[itemUuid]; } // helper recursive prop search+replace From 2ab57b217a34967fc75e1e81a97b60a4c678c9e5 Mon Sep 17 00:00:00 2001 From: "Kristian D. Dimitrov" Date: Wed, 13 Mar 2019 19:09:08 +0200 Subject: [PATCH 23/69] feat: support entitelments, clear TargetAttributes, refactor code --- lib/pbxFile.js | 22 ++++++++++----- lib/pbxProject.js | 68 +++++++++++++++++++++++++++++------------------ 2 files changed, 57 insertions(+), 33 deletions(-) diff --git a/lib/pbxFile.js b/lib/pbxFile.js index 703a91f..766cd1e 100644 --- a/lib/pbxFile.js +++ b/lib/pbxFile.js @@ -24,6 +24,7 @@ var DEFAULT_SOURCETREE = '""', DEFAULT_GROUP = 'Resources', DEFAULT_FILETYPE = 'unknown', HEADER_FILE_TYPE_SUFFIX = ".h", + ENTITLEMENTS_FILE_TYPE_SUFFIX = ".entitlements", SOURCE_CODE_FILE_TYPE_PREFIX = "sourcecode."; var FILETYPE_BY_EXTENSION = { @@ -50,6 +51,7 @@ var FILETYPE_BY_EXTENSION = { octest: 'wrapper.cfbundle', pch: 'sourcecode.c.h', plist: 'text.plist.xml', + entitlements: 'text.plist.entitlements', png: "image.png", sh: 'text.script.sh', swift: 'sourcecode.swift', @@ -73,7 +75,8 @@ var FILETYPE_BY_EXTENSION = { 'sourcecode.c.objc': 'Sources', 'sourcecode.swift': 'Sources', 'sourcecode.cpp.cpp': 'Sources', - 'sourcecode.cpp.objcpp': 'Sources' + 'sourcecode.cpp.objcpp': 'Sources', + 'text.plist.entitlements': 'Reference' //only in file reference }, PATH_BY_FILETYPE = { 'compiled.mach-o.dylib': 'usr/lib/', @@ -101,18 +104,22 @@ var FILETYPE_BY_EXTENSION = { 'text.plist.strings': 4 }; -function isSourceOrHeaderFileType(fileType) { - return fileType.startsWith(SOURCE_CODE_FILE_TYPE_PREFIX); -} - function isHeaderFileType(fileType) { return fileType.endsWith(HEADER_FILE_TYPE_SUFFIX); } +function isSourceFileType(fileType) { + return fileType.startsWith(SOURCE_CODE_FILE_TYPE_PREFIX) && !isHeaderFileType(fileType); +} + function isResource(group) { return group === "Resources"; } +function isEntitlement(fileType) { + return fileType.endsWith(ENTITLEMENTS_FILE_TYPE_SUFFIX); +} + function unquoted(text){ return text == null ? '' : text.replace (/(^")|("$)/g, '') } @@ -263,7 +270,8 @@ function pbxFile(filepath, opt) { module.exports = { pbxFile: pbxFile, - isSourceOrHeaderFileType, + isSourceFileType, isHeaderFileType, - isResource + isResource, + isEntitlement } diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 92f4020..bb2db28 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -23,9 +23,10 @@ var util = require('util'), fork = require('child_process').fork, pbxWriter = require('./pbxWriter'), pbxFile = require('./pbxFile').pbxFile, - isSourceOrHeaderFileType = require('./pbxFile').isSourceOrHeaderFileType, + isSourceFileType = require('./pbxFile').isSourceFileType, isHeaderFileType = require('./pbxFile').isHeaderFileType, isResource = require('./pbxFile').isResource, + isEntitlement = require('./pbxFile').isEntitlement fs = require('fs'), parser = require('./parser/pbxproj'), plist = require('simple-plist'), @@ -560,13 +561,12 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT var srcRootPath = $path.dirname($path.dirname(this.filepath)); var relativePath = $path.relative(srcRootPath, filePath); var file = new pbxFile(opt.filesRelativeToProject ? relativePath : filePath); - + file.uuid = this.generateUuid(); + file.fileRef = this.generateUuid(); if(opt.target) { file.target = opt.target; } - if (fs.existsSync(filePath) && fs.lstatSync(filePath).isDirectory()) { - file.uuid = this.generateUuid(); file.fileRef = file.uuid; var files = fs.readdirSync(filePath).map(p => $path.join(filePath, p)); if($path.extname(filePath) === ".lproj") { @@ -584,27 +584,21 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT pbxGroup.children.push(pbxGroupChild(file)); this.addPbxGroup(files, $path.basename(filePath), filePath, null, {uuid: file.uuid, filesRelativeToProject: opt.filesRelativeToProject, target: opt.target}); } - } else if (isSourceOrHeaderFileType(file.lastKnownFileType)) { - file.uuid = this.generateUuid(); - file.fileRef = this.generateUuid(); - this.addToPbxFileReferenceSection(file); // PBXFileReference - this.addToPbxBuildFileSection(file); // PBXBuildFile - if (!isHeaderFileType(file.lastKnownFileType)) { - this.addToPbxSourcesBuildPhase(file); - } - pbxGroup.children.push(pbxGroupChild(file)); - } else if(isResource(file.group)) { - file.uuid = this.generateUuid(); - file.fileRef = this.generateUuid(); - this.addToPbxFileReferenceSection(file); // PBXFileReference - this.addToPbxResourcesBuildPhase(file) - pbxGroup.children.push(pbxGroupChild(file)); } else { - file.uuid = this.generateUuid(); - file.fileRef = this.generateUuid(); this.addToPbxFileReferenceSection(file); // PBXFileReference - this.addToPbxBuildFileSection(file); pbxGroup.children.push(pbxGroupChild(file)); + if(isHeaderFileType(file.lastKnownFileType)) { + continue; + } else if (isSourceFileType(file.lastKnownFileType)) { + this.addToPbxBuildFileSection(file); // PBXBuildFile + this.addToPbxSourcesBuildPhase(file); + } else if(isEntitlement(file.lastKnownFileType)) { + this.addToBuildSettings('CODE_SIGN_ENTITLEMENTS', file.path, opt.target); + } else if(isResource(file.group)) { + this.addToPbxResourcesBuildPhase(file) + } else { + this.addToPbxBuildFileSection(file); + } } } @@ -1445,14 +1439,30 @@ pbxProject.prototype.removeFromOtherLinkerFlags = function (flag) { } } -pbxProject.prototype.addToBuildSettings = function (buildSetting, value) { +pbxProject.prototype.addToBuildSettings = function (buildSetting, value, targetUuid) { var configurations = nonComments(this.pbxXCBuildConfigurationSection()), + buildConfigurationsUuids = [], config, buildSettings; + if(targetUuid) { + var targets = this.hash.project.objects['PBXNativeTarget'] || []; + var target = targets[targetUuid] || {}; + var buildConfigurationList = target["buildConfigurationList"]; + var pbxXCConfigurationListSection = this.pbxXCConfigurationList() || {}; + var xcConfigurationList = pbxXCConfigurationListSection[buildConfigurationList] || {}; + var buildConfigurations = xcConfigurationList.buildConfigurations || []; + for(var configurationUuid in buildConfigurations){ + buildConfigurationsUuids.push(buildConfigurations[configurationUuid].value); + } + + } + for (config in configurations) { - buildSettings = configurations[config].buildSettings; + if(!target || buildConfigurationsUuids.indexOf(config) >= 0) { + buildSettings = configurations[config].buildSettings; - buildSettings[buildSetting] = value; + buildSettings[buildSetting] = value; + } } } @@ -1762,9 +1772,15 @@ pbxProject.prototype.removeTarget = function(target, targetKey) { } } + //remove targetAttributes for target + var attributes = this.getFirstProject()['firstProject']['attributes']; + if (attributes['TargetAttributes']) { + delete attributes['TargetAttributes'][targetKey]; + } + //remove the target from PBXNativeTarget section var nativeTargets = this.pbxNativeTargetSection(); - removeItemAndCommentFromSectionByUuid(nativeTargets, nativeTargetUuid); + removeItemAndCommentFromSectionByUuid(nativeTargets, targetKey); this.removePbxGroup(unquote(target.name)); }; From 750e7892d7d2b44f0d3077abe3d75177c132d8a0 Mon Sep 17 00:00:00 2001 From: "Kristian D. Dimitrov" Date: Sun, 17 Mar 2019 17:38:27 +0200 Subject: [PATCH 24/69] fix: plist added to build phase, assets not added to resources --- lib/pbxFile.js | 15 ++++++++++--- lib/pbxProject.js | 54 ++++++++++++++++++++++++++++++----------------- 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/lib/pbxFile.js b/lib/pbxFile.js index 766cd1e..8ca0371 100644 --- a/lib/pbxFile.js +++ b/lib/pbxFile.js @@ -75,8 +75,7 @@ var FILETYPE_BY_EXTENSION = { 'sourcecode.c.objc': 'Sources', 'sourcecode.swift': 'Sources', 'sourcecode.cpp.cpp': 'Sources', - 'sourcecode.cpp.objcpp': 'Sources', - 'text.plist.entitlements': 'Reference' //only in file reference + 'sourcecode.cpp.objcpp': 'Sources' }, PATH_BY_FILETYPE = { 'compiled.mach-o.dylib': 'usr/lib/', @@ -112,6 +111,10 @@ function isSourceFileType(fileType) { return fileType.startsWith(SOURCE_CODE_FILE_TYPE_PREFIX) && !isHeaderFileType(fileType); } +function isAssetFileType(fileType) { + return fileType === FILETYPE_BY_EXTENSION.xcassets; +} + function isResource(group) { return group === "Resources"; } @@ -120,6 +123,10 @@ function isEntitlement(fileType) { return fileType.endsWith(ENTITLEMENTS_FILE_TYPE_SUFFIX); } +function isPlist(fileType) { + return fileType === FILETYPE_BY_EXTENSION.plist; +} + function unquoted(text){ return text == null ? '' : text.replace (/(^")|("$)/g, '') } @@ -273,5 +280,7 @@ module.exports = { isSourceFileType, isHeaderFileType, isResource, - isEntitlement + isEntitlement, + isAssetFileType, + isPlist } diff --git a/lib/pbxProject.js b/lib/pbxProject.js index bb2db28..c047e2c 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -26,7 +26,9 @@ var util = require('util'), isSourceFileType = require('./pbxFile').isSourceFileType, isHeaderFileType = require('./pbxFile').isHeaderFileType, isResource = require('./pbxFile').isResource, - isEntitlement = require('./pbxFile').isEntitlement + isEntitlement = require('./pbxFile').isEntitlement, + isAssetFileType = require('./pbxFile').isAssetFileType, + isPlist = require('./pbxFile').isPlist, fs = require('fs'), parser = require('./parser/pbxproj'), plist = require('simple-plist'), @@ -566,18 +568,11 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT if(opt.target) { file.target = opt.target; } - if (fs.existsSync(filePath) && fs.lstatSync(filePath).isDirectory()) { + if (fs.existsSync(filePath) && fs.lstatSync(filePath).isDirectory() && !isAssetFileType(file.lastKnownFileType)) { file.fileRef = file.uuid; var files = fs.readdirSync(filePath).map(p => $path.join(filePath, p)); if($path.extname(filePath) === ".lproj") { - for (var i = 0; i < files.length; i++) { - var variantGroup = this.addLocalizationVariantGroup($path.basename(files[i]), { target: opt.target, skipAddToResourcesGroup: true }); - var refFile = new pbxFile($path.relative(srcRootPath, files[i]), {basename: $path.parse(file.basename).name}); - refFile.fileRef = this.generateUuid(); - this.addToPbxFileReferenceSection(refFile); - this.addToPbxVariantGroup(refFile, variantGroup.fileRef); - pbxGroup.children.push(pbxGroupChild(variantGroup)); - } + addLocalizationGroup.call(this, pbxGroup, file, files, srcRootPath, opt); } else { this.addToPbxFileReferenceSection(file); // PBXFileReference this.addToPbxBuildFileSection(file); @@ -587,18 +582,22 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT } else { this.addToPbxFileReferenceSection(file); // PBXFileReference pbxGroup.children.push(pbxGroupChild(file)); - if(isHeaderFileType(file.lastKnownFileType)) { + if(isHeaderFileType(file.lastKnownFileType) || isPlist(file.lastKnownFileType)) { continue; - } else if (isSourceFileType(file.lastKnownFileType)) { - this.addToPbxBuildFileSection(file); // PBXBuildFile - this.addToPbxSourcesBuildPhase(file); - } else if(isEntitlement(file.lastKnownFileType)) { + } + + if(isEntitlement(file.lastKnownFileType)) { this.addToBuildSettings('CODE_SIGN_ENTITLEMENTS', file.path, opt.target); + continue; + } + + if (isSourceFileType(file.lastKnownFileType)) { // PBXBuildFile + this.addToPbxSourcesBuildPhase(file); } else if(isResource(file.group)) { this.addToPbxResourcesBuildPhase(file) - } else { - this.addToPbxBuildFileSection(file); } + + this.addToPbxBuildFileSection(file); } } @@ -619,6 +618,21 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT return {uuid: pbxGroupUuid, pbxGroup: pbxGroup}; } +function addLocalizationGroup(pbxGroup, variantFile, files, srcRootPath, opt) { + for (var i = 0; i < files.length; i++) { + var variantGroupName = $path.parse($path.basename(files[i])).name + ".storyboard"; + var variantGroup = this.findPBXVariantGroupKey({name: variantGroupName}); + if(!variantGroup) { + variantGroup = this.addLocalizationVariantGroup(variantGroupName, { target: opt.target, skipAddToResourcesGroup: true }); + pbxGroup.children.push(pbxGroupChild(variantGroup)); + } + var refFile = new pbxFile($path.relative(srcRootPath, files[i]), {basename: $path.parse(variantFile.basename).name}); + refFile.fileRef = this.generateUuid(); + this.addToPbxFileReferenceSection(refFile); + this.addToPbxVariantGroup(refFile, variantGroup.fileRef); + } +} + pbxProject.prototype.removePbxGroup = function(groupName, path) { var group = this.pbxGroupByName(groupName); if (!group) { @@ -1375,15 +1389,17 @@ pbxProject.prototype.removeFromHeaderSearchPaths = function(file) { } } -pbxProject.prototype.addToHeaderSearchPaths = function(file) { +pbxProject.prototype.addToHeaderSearchPaths = function(file, productName) { var configurations = nonComments(this.pbxXCBuildConfigurationSection()), INHERITED = '"$(inherited)"', config, buildSettings, searchPaths; + productName = unquote(productName || this.productName); + for (config in configurations) { buildSettings = configurations[config].buildSettings; - if (unquote(buildSettings['PRODUCT_NAME']) != this.productName) + if (unquote(buildSettings['PRODUCT_NAME']) != productName) continue; if (!buildSettings['HEADER_SEARCH_PATHS']) { From 054facf2d04af7aa3d75e0b9a3797c69c8e83b47 Mon Sep 17 00:00:00 2001 From: "Kristian D. Dimitrov" Date: Sun, 17 Mar 2019 17:42:08 +0200 Subject: [PATCH 25/69] feat: handle localization items properly --- lib/pbxProject.js | 86 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 26 deletions(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index c047e2c..7758a60 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -517,6 +517,7 @@ pbxProject.prototype.findMainPbxGroup = function () { pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceTree, opt) { opt = opt || {}; + var srcRootPath = $path.dirname($path.dirname(this.filepath)); var oldGroup = this.pbxGroupByName(name); if (oldGroup) { this.removePbxGroup(name, path); @@ -560,7 +561,6 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT continue; } - var srcRootPath = $path.dirname($path.dirname(this.filepath)); var relativePath = $path.relative(srcRootPath, filePath); var file = new pbxFile(opt.filesRelativeToProject ? relativePath : filePath); file.uuid = this.generateUuid(); @@ -569,22 +569,21 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT file.target = opt.target; } if (fs.existsSync(filePath) && fs.lstatSync(filePath).isDirectory() && !isAssetFileType(file.lastKnownFileType)) { - file.fileRef = file.uuid; - var files = fs.readdirSync(filePath).map(p => $path.join(filePath, p)); if($path.extname(filePath) === ".lproj") { - addLocalizationGroup.call(this, pbxGroup, file, files, srcRootPath, opt); - } else { - this.addToPbxFileReferenceSection(file); // PBXFileReference - this.addToPbxBuildFileSection(file); - pbxGroup.children.push(pbxGroupChild(file)); - this.addPbxGroup(files, $path.basename(filePath), filePath, null, {uuid: file.uuid, filesRelativeToProject: opt.filesRelativeToProject, target: opt.target}); + continue; } + file.fileRef = file.uuid; + var files = fs.readdirSync(filePath).map(p => $path.join(filePath, p)); + this.addToPbxFileReferenceSection(file); // PBXFileReference + this.addToPbxBuildFileSection(file); + pbxGroup.children.push(pbxGroupChild(file)); + this.addPbxGroup(files, $path.basename(filePath), filePath, null, {uuid: file.uuid, filesRelativeToProject: opt.filesRelativeToProject, target: opt.target}); } else { this.addToPbxFileReferenceSection(file); // PBXFileReference pbxGroup.children.push(pbxGroupChild(file)); if(isHeaderFileType(file.lastKnownFileType) || isPlist(file.lastKnownFileType)) { continue; - } + } if(isEntitlement(file.lastKnownFileType)) { this.addToBuildSettings('CODE_SIGN_ENTITLEMENTS', file.path, opt.target); @@ -601,6 +600,8 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT } } + handleLocalization.call(this, filePathsArray, pbxGroup, srcRootPath, opt); + if (groups) { groups[pbxGroupUuid] = pbxGroup; groups[commentKey] = name; @@ -618,26 +619,55 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT return {uuid: pbxGroupUuid, pbxGroup: pbxGroup}; } -function addLocalizationGroup(pbxGroup, variantFile, files, srcRootPath, opt) { - for (var i = 0; i < files.length; i++) { - var variantGroupName = $path.parse($path.basename(files[i])).name + ".storyboard"; - var variantGroup = this.findPBXVariantGroupKey({name: variantGroupName}); - if(!variantGroup) { - variantGroup = this.addLocalizationVariantGroup(variantGroupName, { target: opt.target, skipAddToResourcesGroup: true }); - pbxGroup.children.push(pbxGroupChild(variantGroup)); +function handleLocalization(files, pbxGroup, srcRootPath, opt) { + var storyboardNames = {}; + var allNames = {}; + var regions = {}; + + for (let i = 0; i < files.length; i++) { + const filePath = files[i]; + const parsedPath = $path.parse(filePath); + if($path.extname(filePath) === ".lproj") { + var regionName = parsedPath.name; + var region = regions[regionName] = {}; + var regionFiles = fs.readdirSync(filePath); + this.addKnownRegion(regionName); + for (let j = 0; j < regionFiles.length; j++) { + var regionFilePath = regionFiles[j]; + var parsedRegionFilePath = $path.parse(regionFilePath); + var regionFileName = parsedRegionFilePath.name; + if(parsedRegionFilePath.ext === ".storyboard") { + storyboardNames[parsedRegionFilePath.name] = true; + } + fileRegions = allNames[parsedRegionFilePath.name] = allNames[parsedRegionFilePath.name] || []; + fileRegions.push(regionName); + region[regionFileName] = $path.join(filePath, regionFilePath); + } } - var refFile = new pbxFile($path.relative(srcRootPath, files[i]), {basename: $path.parse(variantFile.basename).name}); - refFile.fileRef = this.generateUuid(); - this.addToPbxFileReferenceSection(refFile); - this.addToPbxVariantGroup(refFile, variantGroup.fileRef); } -} + + for (var name in allNames) { + fileRegions = allNames[name] + var variantGroupName = storyboardNames[name] ? name + ".storyboard" : name + ".strings"; + + var variantGroup = this.addLocalizationVariantGroup(variantGroupName, { target: opt.target, skipAddToResourcesGroup: true }); + pbxGroup.children.push(pbxGroupChild(variantGroup)); + for (let k = 0; k < fileRegions.length; k++) { + var file = regions[fileRegions[k]][name]; + var refFile = new pbxFile($path.relative(srcRootPath, file), {basename: fileRegions[k]}); + refFile.fileRef = this.generateUuid(); + this.addToPbxFileReferenceSection(refFile); + this.addToPbxVariantGroup(refFile, variantGroup.fileRef); + } + } +}; pbxProject.prototype.removePbxGroup = function(groupName, path) { - var group = this.pbxGroupByName(groupName); - if (!group) { + var groupKey = this.findPBXGroupKey({name: groupName}) || this.findPBXVariantGroupKey({name: groupName}); + if (!groupKey) { return; } + var group = this.getPBXGroupByKey(groupKey) || this.getPBXVariantGroupByKey(groupKey) path = path || ""; @@ -663,8 +693,12 @@ pbxProject.prototype.removePbxGroup = function(groupName, path) { } } - var section = this.hash.project.objects['PBXGroup'], - key, itemKey; + var section, key, itemKey; + if(unquote(group.isa) === "PBXVariantGroup") { + section = this.hash.project.objects['PBXVariantGroup']; + } else { + section = this.hash.project.objects['PBXGroup']; + } for (key in section) { // only look for comments From 64ea6c0edf14b6444c743eeb2d1df90dcc6e67da Mon Sep 17 00:00:00 2001 From: "Kristian D. Dimitrov" Date: Tue, 19 Mar 2019 13:32:00 +0200 Subject: [PATCH 26/69] refactor: extract constants in separate file --- lib/constants.js | 135 ++++++++++++++++++++++ lib/pbxFile.js | 162 +++------------------------ lib/pbxProject.js | 57 +++++----- package.json | 2 +- test/BuildSettings.js | 2 +- test/FrameworkSearchPaths.js | 2 +- test/HeaderSearchPaths.js | 2 +- test/LibrarySearchPaths.js | 2 +- test/OtherLinkerFlags.js | 2 +- test/addFramework.js | 2 +- test/addHeaderFile.js | 2 +- test/addResourceFile.js | 2 +- test/addSourceFile.js | 2 +- test/addStaticLibrary.js | 2 +- test/addToPbxFileReferenceSection.js | 2 +- test/dataModelDocument.js | 2 +- test/group.js | 2 +- test/multipleTargets.js | 2 +- test/pbxFile.js | 2 +- test/removeFramework.js | 2 +- test/removeHeaderFile.js | 2 +- test/removeResourceFile.js | 2 +- test/removeSourceFile.js | 2 +- test/xcode5searchPaths.js | 2 +- 24 files changed, 202 insertions(+), 194 deletions(-) create mode 100644 lib/constants.js diff --git a/lib/constants.js b/lib/constants.js new file mode 100644 index 0000000..e5c3155 --- /dev/null +++ b/lib/constants.js @@ -0,0 +1,135 @@ +var DEFAULT_SOURCETREE = '""', + DEFAULT_PRODUCT_SOURCETREE = 'BUILT_PRODUCTS_DIR', + DEFAULT_FILEENCODING = 4, + DEFAULT_GROUP = 'Resources', + DEFAULT_FILETYPE = 'unknown', + HEADER_FILE_TYPE_SUFFIX = ".h", + ENTITLEMENTS_FILE_TYPE_SUFFIX = ".entitlements", + SOURCE_CODE_FILE_TYPE_PREFIX = "sourcecode."; + +var FILETYPE_BY_EXTENSION = { + a: 'archive.ar', + app: 'wrapper.application', + appex: 'wrapper.app-extension', + bundle: 'wrapper.plug-in', + c: 'sourcecode.c.c', + cc: 'sourcecode.cpp.cpp', + cpp: 'sourcecode.cpp.cpp', + cxx: 'sourcecode.cpp.cpp', + 'c++': 'sourcecode.cpp.cpp', + dylib: 'compiled.mach-o.dylib', + framework: 'wrapper.framework', + h: 'sourcecode.c.h', + hh: 'sourcecode.cpp.h', + hpp: 'sourcecode.cpp.h', + hxx: 'sourcecode.cpp.h', + 'h++': 'sourcecode.cpp.h', + m: 'sourcecode.c.objc', + mm: 'sourcecode.cpp.objcpp', + markdown: 'text', + mdimporter: 'wrapper.cfbundle', + octest: 'wrapper.cfbundle', + pch: 'sourcecode.c.h', + plist: 'text.plist.xml', + entitlements: 'text.plist.entitlements', + png: "image.png", + sh: 'text.script.sh', + swift: 'sourcecode.swift', + tbd: 'sourcecode.text-based-dylib-definition', + xcassets: 'folder.assetcatalog', + xcconfig: 'text.xcconfig', + xcdatamodel: 'wrapper.xcdatamodel', + xcodeproj: 'wrapper.pb-project', + xctest: 'wrapper.cfbundle', + xib: 'file.xib', + strings: 'text.plist.strings' + }, + GROUP_BY_FILETYPE = { + 'archive.ar': 'Frameworks', + 'compiled.mach-o.dylib': 'Frameworks', + 'sourcecode.text-based-dylib-definition': 'Frameworks', + 'wrapper.framework': 'Frameworks', + 'embedded.framework': 'Embed Frameworks', + 'sourcecode.c.h': 'Resources', + 'sourcecode.c.c': 'Sources', + 'sourcecode.c.objc': 'Sources', + 'sourcecode.swift': 'Sources', + 'sourcecode.cpp.cpp': 'Sources', + 'sourcecode.cpp.objcpp': 'Sources' + }, + PATH_BY_FILETYPE = { + 'compiled.mach-o.dylib': 'usr/lib/', + 'sourcecode.text-based-dylib-definition': 'usr/lib/', + 'wrapper.framework': 'System/Library/Frameworks/' + }, + SOURCETREE_BY_FILETYPE = { + 'compiled.mach-o.dylib': 'SDKROOT', + 'sourcecode.text-based-dylib-definition': 'SDKROOT', + 'wrapper.framework': 'SDKROOT' + }, + ENCODING_BY_FILETYPE = { + 'sourcecode.c.h': 4, + 'sourcecode.c.h': 4, + 'sourcecode.cpp.h': 4, + 'sourcecode.c.c': 4, + 'sourcecode.c.objc': 4, + 'sourcecode.cpp.cpp': 4, + 'sourcecode.cpp.objcpp': 4, + 'sourcecode.swift': 4, + 'text': 4, + 'text.plist.xml': 4, + 'text.script.sh': 4, + 'text.xcconfig': 4, + 'text.plist.strings': 4 + }; + +function isHeaderFileType(fileType) { + return fileType.endsWith(HEADER_FILE_TYPE_SUFFIX); +} + +function isSourceFileType(fileType) { + return fileType.startsWith(SOURCE_CODE_FILE_TYPE_PREFIX) && !isHeaderFileType(fileType); +} + +function isAssetFileType(fileType) { + return fileType === FILETYPE_BY_EXTENSION.xcassets; +} + +function isResource(group) { + return group === "Resources"; +} + +function isEntitlementFileType(fileType) { + return fileType.endsWith(ENTITLEMENTS_FILE_TYPE_SUFFIX); +} + +function isPlistFileType(fileType) { + return fileType === FILETYPE_BY_EXTENSION.plist; +} + +function unquoted(text) { + return text == null ? '' : text.replace (/(^")|("$)/g, '') +} + +module.exports = { + DEFAULT_SOURCETREE, + DEFAULT_PRODUCT_SOURCETREE, + DEFAULT_FILEENCODING, + DEFAULT_GROUP, + DEFAULT_FILETYPE, + HEADER_FILE_TYPE_SUFFIX, + ENTITLEMENTS_FILE_TYPE_SUFFIX, + SOURCE_CODE_FILE_TYPE_PREFIX, + FILETYPE_BY_EXTENSION, + GROUP_BY_FILETYPE, + PATH_BY_FILETYPE, + SOURCETREE_BY_FILETYPE, + ENCODING_BY_FILETYPE, + isHeaderFileType, + isSourceFileType, + isAssetFileType, + isResource, + isEntitlementFileType, + isPlistFileType, + unquoted +} \ No newline at end of file diff --git a/lib/pbxFile.js b/lib/pbxFile.js index 8ca0371..1b52d25 100644 --- a/lib/pbxFile.js +++ b/lib/pbxFile.js @@ -16,134 +16,24 @@ */ var path = require('path'), - util = require('util'); - -var DEFAULT_SOURCETREE = '""', - DEFAULT_PRODUCT_SOURCETREE = 'BUILT_PRODUCTS_DIR', - DEFAULT_FILEENCODING = 4, - DEFAULT_GROUP = 'Resources', - DEFAULT_FILETYPE = 'unknown', - HEADER_FILE_TYPE_SUFFIX = ".h", - ENTITLEMENTS_FILE_TYPE_SUFFIX = ".entitlements", - SOURCE_CODE_FILE_TYPE_PREFIX = "sourcecode."; - -var FILETYPE_BY_EXTENSION = { - a: 'archive.ar', - app: 'wrapper.application', - appex: 'wrapper.app-extension', - bundle: 'wrapper.plug-in', - c: 'sourcecode.c.c', - cc: 'sourcecode.cpp.cpp', - cpp: 'sourcecode.cpp.cpp', - cxx: 'sourcecode.cpp.cpp', - 'c++': 'sourcecode.cpp.cpp', - dylib: 'compiled.mach-o.dylib', - framework: 'wrapper.framework', - h: 'sourcecode.c.h', - hh: 'sourcecode.cpp.h', - hpp: 'sourcecode.cpp.h', - hxx: 'sourcecode.cpp.h', - 'h++': 'sourcecode.cpp.h', - m: 'sourcecode.c.objc', - mm: 'sourcecode.cpp.objcpp', - markdown: 'text', - mdimporter: 'wrapper.cfbundle', - octest: 'wrapper.cfbundle', - pch: 'sourcecode.c.h', - plist: 'text.plist.xml', - entitlements: 'text.plist.entitlements', - png: "image.png", - sh: 'text.script.sh', - swift: 'sourcecode.swift', - tbd: 'sourcecode.text-based-dylib-definition', - xcassets: 'folder.assetcatalog', - xcconfig: 'text.xcconfig', - xcdatamodel: 'wrapper.xcdatamodel', - xcodeproj: 'wrapper.pb-project', - xctest: 'wrapper.cfbundle', - xib: 'file.xib', - strings: 'text.plist.strings' - }, - GROUP_BY_FILETYPE = { - 'archive.ar': 'Frameworks', - 'compiled.mach-o.dylib': 'Frameworks', - 'sourcecode.text-based-dylib-definition': 'Frameworks', - 'wrapper.framework': 'Frameworks', - 'embedded.framework': 'Embed Frameworks', - 'sourcecode.c.h': 'Resources', - 'sourcecode.c.c': 'Sources', - 'sourcecode.c.objc': 'Sources', - 'sourcecode.swift': 'Sources', - 'sourcecode.cpp.cpp': 'Sources', - 'sourcecode.cpp.objcpp': 'Sources' - }, - PATH_BY_FILETYPE = { - 'compiled.mach-o.dylib': 'usr/lib/', - 'sourcecode.text-based-dylib-definition': 'usr/lib/', - 'wrapper.framework': 'System/Library/Frameworks/' - }, - SOURCETREE_BY_FILETYPE = { - 'compiled.mach-o.dylib': 'SDKROOT', - 'sourcecode.text-based-dylib-definition': 'SDKROOT', - 'wrapper.framework': 'SDKROOT' - }, - ENCODING_BY_FILETYPE = { - 'sourcecode.c.h': 4, - 'sourcecode.c.h': 4, - 'sourcecode.cpp.h': 4, - 'sourcecode.c.c': 4, - 'sourcecode.c.objc': 4, - 'sourcecode.cpp.cpp': 4, - 'sourcecode.cpp.objcpp': 4, - 'sourcecode.swift': 4, - 'text': 4, - 'text.plist.xml': 4, - 'text.script.sh': 4, - 'text.xcconfig': 4, - 'text.plist.strings': 4 - }; - -function isHeaderFileType(fileType) { - return fileType.endsWith(HEADER_FILE_TYPE_SUFFIX); -} - -function isSourceFileType(fileType) { - return fileType.startsWith(SOURCE_CODE_FILE_TYPE_PREFIX) && !isHeaderFileType(fileType); -} - -function isAssetFileType(fileType) { - return fileType === FILETYPE_BY_EXTENSION.xcassets; -} - -function isResource(group) { - return group === "Resources"; -} - -function isEntitlement(fileType) { - return fileType.endsWith(ENTITLEMENTS_FILE_TYPE_SUFFIX); -} - -function isPlist(fileType) { - return fileType === FILETYPE_BY_EXTENSION.plist; -} - -function unquoted(text){ - return text == null ? '' : text.replace (/(^")|("$)/g, '') -} + util = require('util'), + constants = require('./constants'), + unquoted = constants.unquoted, + FILETYPE_BY_EXTENSION = constants.FILETYPE_BY_EXTENSION; function detectType(filePath) { var extension = path.extname(filePath).substring(1), filetype = FILETYPE_BY_EXTENSION[unquoted(extension)]; if (!filetype) { - return DEFAULT_FILETYPE; + return constants.DEFAULT_FILETYPE; } return filetype; } function defaultExtension(fileRef) { - var filetype = fileRef.lastKnownFileType && fileRef.lastKnownFileType != DEFAULT_FILETYPE ? + var filetype = fileRef.lastKnownFileType && fileRef.lastKnownFileType != constants.DEFAULT_FILETYPE ? fileRef.lastKnownFileType : fileRef.explicitFileType; for(var extension in FILETYPE_BY_EXTENSION) { @@ -156,7 +46,7 @@ function defaultExtension(fileRef) { function defaultEncoding(fileRef) { var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType, - encoding = ENCODING_BY_FILETYPE[unquoted(filetype)]; + encoding = constants.ENCODING_BY_FILETYPE[unquoted(filetype)]; if (encoding) { return encoding; @@ -166,18 +56,18 @@ function defaultEncoding(fileRef) { function detectGroup(fileRef, opt) { var extension = path.extname(fileRef.basename).substring(1), filetype = fileRef.lastKnownFileType || fileRef.explicitFileType, - groupName = GROUP_BY_FILETYPE[unquoted(filetype)]; + groupName = constants.GROUP_BY_FILETYPE[unquoted(filetype)]; if (extension === 'xcdatamodeld') { return 'Sources'; } if (opt.customFramework && opt.embed) { - return GROUP_BY_FILETYPE['embedded.framework']; + return constants.GROUP_BY_FILETYPE['embedded.framework']; } if (!groupName) { - return DEFAULT_GROUP; + return constants.DEFAULT_GROUP; } return groupName; @@ -186,18 +76,18 @@ function detectGroup(fileRef, opt) { function detectSourcetree(fileRef) { var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType, - sourcetree = SOURCETREE_BY_FILETYPE[unquoted(filetype)]; + sourcetree = constants.SOURCETREE_BY_FILETYPE[unquoted(filetype)]; if (fileRef.explicitFileType) { - return DEFAULT_PRODUCT_SOURCETREE; + return constants.DEFAULT_PRODUCT_SOURCETREE; } if (fileRef.customFramework) { - return DEFAULT_SOURCETREE; + return constants.DEFAULT_SOURCETREE; } if (!sourcetree) { - return DEFAULT_SOURCETREE; + return constants.DEFAULT_SOURCETREE; } return sourcetree; @@ -205,7 +95,7 @@ function detectSourcetree(fileRef) { function defaultPath(fileRef, filePath) { var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType, - defaultPath = PATH_BY_FILETYPE[unquoted(filetype)]; + defaultPath = constants.PATH_BY_FILETYPE[unquoted(filetype)]; if (fileRef.customFramework) { return filePath; @@ -218,18 +108,8 @@ function defaultPath(fileRef, 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 || {}; + opt = opt || {}; this.basename = opt.basename || path.basename(filepath); this.lastKnownFileType = opt.lastKnownFileType || detectType(filepath); @@ -275,12 +155,4 @@ function pbxFile(filepath, opt) { } } -module.exports = { - pbxFile: pbxFile, - isSourceFileType, - isHeaderFileType, - isResource, - isEntitlement, - isAssetFileType, - isPlist -} +module.exports = pbxFile; \ No newline at end of file diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 7758a60..d08c55a 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -22,18 +22,19 @@ var util = require('util'), $uuid = require('uuid'), fork = require('child_process').fork, pbxWriter = require('./pbxWriter'), - pbxFile = require('./pbxFile').pbxFile, - isSourceFileType = require('./pbxFile').isSourceFileType, - isHeaderFileType = require('./pbxFile').isHeaderFileType, - isResource = require('./pbxFile').isResource, - isEntitlement = require('./pbxFile').isEntitlement, - isAssetFileType = require('./pbxFile').isAssetFileType, - isPlist = require('./pbxFile').isPlist, + pbxFile = require('./pbxFile'), + constants = require('./constants'), fs = require('fs'), parser = require('./parser/pbxproj'), plist = require('simple-plist'), COMMENT_KEY = /_comment$/, - NO_SPECIAL_SYMBOLS = /^[a-zA-Z0-9_\.\$]+\.[a-zA-Z]+$/; + NO_SPECIAL_SYMBOLS = /^[a-zA-Z0-9_\.\$]+\.[a-zA-Z]+$/, + isSourceFileType = constants.isSourceFileType, + isHeaderFileType = constants.isHeaderFileType, + isResource = constants.isResource, + isEntitlementFileType = constants.isEntitlementFileType, + isAssetFileType = constants.isAssetFileType, + isPlistFileType = constants.isPlistFileType; function pbxProject(filename) { if (!(this instanceof pbxProject)) @@ -81,7 +82,7 @@ pbxProject.prototype.allUuids = function() { uuids = [], section; - for (key in sections) { + for (var key in sections) { section = sections[key] uuids = uuids.concat(Object.keys(section)) } @@ -440,7 +441,7 @@ pbxProject.prototype.removeCopyfile = function(fpath, opt) { pbxProject.prototype.removeFromPbxCopyfilesBuildPhase = function(file) { var sources = this.pbxCopyfilesBuildPhaseObj(file.target); - for (i in sources.files) { + for (var i in sources.files) { if (sources.files[i].comment == longComment(file)) { sources.files.splice(i, 1); break; @@ -581,11 +582,11 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT } else { this.addToPbxFileReferenceSection(file); // PBXFileReference pbxGroup.children.push(pbxGroupChild(file)); - if(isHeaderFileType(file.lastKnownFileType) || isPlist(file.lastKnownFileType)) { + if(isHeaderFileType(file.lastKnownFileType) || isPlistFileType(file.lastKnownFileType)) { continue; } - if(isEntitlement(file.lastKnownFileType)) { + if(isEntitlementFileType(file.lastKnownFileType)) { this.addToBuildSettings('CODE_SIGN_ENTITLEMENTS', file.path, opt.target); continue; } @@ -839,7 +840,7 @@ pbxProject.prototype.removeFromFrameworksPbxGroup = function(file) { } var pluginsGroupChildren = this.pbxGroupByName('Frameworks').children; - for (i in pluginsGroupChildren) { + for (var i in pluginsGroupChildren) { if (pbxGroupChild(file).value == pluginsGroupChildren[i].value && pbxGroupChild(file).comment == pluginsGroupChildren[i].comment) { pluginsGroupChildren.splice(i, 1); @@ -859,7 +860,7 @@ pbxProject.prototype.removeFromPbxEmbedFrameworksBuildPhase = function (file) { var sources = this.pbxEmbedFrameworksBuildPhaseObj(file.target); if (sources) { var files = []; - for (i in sources.files) { + for (var i in sources.files) { if (sources.files[i].comment != longComment(file)) { files.push(sources.files[i]); } @@ -930,7 +931,7 @@ pbxProject.prototype.addToPbxFrameworksBuildPhase = function(file) { pbxProject.prototype.removeFromPbxFrameworksBuildPhase = function(file) { var sources = this.pbxFrameworksBuildPhaseObj(file.target); - for (i in sources.files) { + for (var i in sources.files) { if (sources.files[i].comment == longComment(file)) { sources.files.splice(i, 1); break; @@ -1075,8 +1076,8 @@ pbxProject.prototype.addBuildPhase = function(filePathsArray, buildPhaseType, co if (!COMMENT_KEY.test(key)) continue; var buildFileKey = key.split(COMMENT_KEY)[0], - buildFile = buildFileSection[buildFileKey]; - fileReference = fileReferenceSection[buildFile.fileRef]; + buildFile = buildFileSection[buildFileKey], + fileReference = fileReferenceSection[buildFile.fileRef]; if (!fileReference) continue; @@ -1649,7 +1650,7 @@ pbxProject.prototype.addTarget = function(name, type, subfolder) { // this.addBuildPhaseToTarget(newPhase.buildPhase, this.getFirstTarget().uuid) - }; + } // Target: Add uuid to root project this.addToPbxProjectSection(target); @@ -1684,13 +1685,13 @@ pbxProject.prototype.removeTarget = function(target, targetKey) { var sectionUuid = buildPhase.value; var section = {}; //in case we don't recognise the section if(buildPhase.comment === buildPhaseNameForIsa("PBXSourcesBuildPhase")){ - var section = this.hash.project.objects["PBXSourcesBuildPhase"]; + section = this.hash.project.objects["PBXSourcesBuildPhase"]; files = files.concat(section[sectionUuid].files); } else if (buildPhase.comment === buildPhaseNameForIsa("PBXResourcesBuildPhase")) { - var section = this.hash.project.objects["PBXResourcesBuildPhase"]; + section = this.hash.project.objects["PBXResourcesBuildPhase"]; files = files.concat(section[sectionUuid].files); } else if (buildPhase.comment === buildPhaseNameForIsa("PBXFrameworksBuildPhase")) { - var section = this.hash.project.objects["PBXFrameworksBuildPhase"]; + section = this.hash.project.objects["PBXFrameworksBuildPhase"]; files = files.concat(section[sectionUuid].files); } @@ -1737,7 +1738,7 @@ pbxProject.prototype.removeTarget = function(target, targetKey) { // the productReference is the uuid from the PBXFileReference Section, but we need the one in PBXBuildFile section // check the fileRef of all records until we find the product - for (uuid in pbxBuildFileSectionNoComments) { + for (var uuid in pbxBuildFileSectionNoComments) { if (this.pbxBuildFileSection()[uuid].fileRef == productReferenceUuid) { productUuid = uuid; } @@ -1804,13 +1805,13 @@ pbxProject.prototype.removeTarget = function(target, targetKey) { var pbxContainerItemProxySection = this.hash.project.objects[pbxContainerItemProxy]; for(var targetDependencyUuid in pbxTargetDependencySectionNoComments) { - targetDependency = pbxTargetDependencySectionNoComments[targetDependencyUuid]; + var targetDependency = pbxTargetDependencySectionNoComments[targetDependencyUuid]; if(targetDependency.target === targetKey) { //remove the PBXContainerItemProxy removeItemAndCommentFromSectionByUuid(pbxContainerItemProxySection, targetDependency.targetProxy); //remove the PBXTargetDependency from dependencies from all targets - for (var nativeTargetUuid in nativeTargetsnoComments) { - const nativeTarget = nativeTargetsnoComments[nativeTargetUuid]; + for (var nativeTargetKey in nativeTargetsnoComments) { + const nativeTarget = nativeTargetsnoComments[nativeTargetKey]; for (var dependencyIndex in nativeTarget.dependencies) { if (nativeTarget.dependencies[dependencyIndex].value == targetDependencyUuid) { nativeTarget.dependencies.splice(dependencyIndex, 1); @@ -2061,7 +2062,7 @@ function unquote(str) { function buildPhaseNameForIsa (isa) { - BUILDPHASENAME_BY_ISA = { + var BUILDPHASENAME_BY_ISA = { PBXCopyFilesBuildPhase: 'Copy Files', PBXResourcesBuildPhase: 'Resources', PBXSourcesBuildPhase: 'Sources', @@ -2073,7 +2074,7 @@ function buildPhaseNameForIsa (isa) { function producttypeForTargettype (targetType) { - PRODUCTTYPE_BY_TARGETTYPE = { + var PRODUCTTYPE_BY_TARGETTYPE = { application: 'com.apple.product-type.application', app_extension: 'com.apple.product-type.app-extension', bundle: 'com.apple.product-type.bundle', @@ -2091,7 +2092,7 @@ function producttypeForTargettype (targetType) { function filetypeForProducttype (productType) { - FILETYPE_BY_PRODUCTTYPE = { + var 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"', diff --git a/package.json b/package.json index 4d589aa..8ded6af 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Telerik ", "name": "nativescript-dev-xcode", "description": "parser for xcodeproj/project.pbxproj files", - "main":"index.js", + "main": "index.js", "version": "0.1.0", "repository": { "url": "https://github.com/NativeScript/nativescript-dev-xcode.git" diff --git a/test/BuildSettings.js b/test/BuildSettings.js index 698ce06..213f575 100644 --- a/test/BuildSettings.js +++ b/test/BuildSettings.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), proj = new pbx('.'); function cleanHash() { diff --git a/test/FrameworkSearchPaths.js b/test/FrameworkSearchPaths.js index d6fb0ce..b709f3a 100644 --- a/test/FrameworkSearchPaths.js +++ b/test/FrameworkSearchPaths.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), proj = new pbx('.'); var pbxFile = { diff --git a/test/HeaderSearchPaths.js b/test/HeaderSearchPaths.js index 1377384..998fd8b 100644 --- a/test/HeaderSearchPaths.js +++ b/test/HeaderSearchPaths.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), proj = new pbx('.'); function cleanHash() { diff --git a/test/LibrarySearchPaths.js b/test/LibrarySearchPaths.js index 5b1461b..6788e10 100644 --- a/test/LibrarySearchPaths.js +++ b/test/LibrarySearchPaths.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), proj = new pbx('.'); function cleanHash() { diff --git a/test/OtherLinkerFlags.js b/test/OtherLinkerFlags.js index f77ea8f..de59f4c 100644 --- a/test/OtherLinkerFlags.js +++ b/test/OtherLinkerFlags.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), proj = new pbx('.'); function cleanHash() { diff --git a/test/addFramework.js b/test/addFramework.js index 11358ef..17b5551 100644 --- a/test/addFramework.js +++ b/test/addFramework.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), proj = new pbx('.'); function cleanHash() { diff --git a/test/addHeaderFile.js b/test/addHeaderFile.js index f96a736..2373405 100644 --- a/test/addHeaderFile.js +++ b/test/addHeaderFile.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), proj = new pbx('.'); function cleanHash() { diff --git a/test/addResourceFile.js b/test/addResourceFile.js index 04b6013..3c48c59 100644 --- a/test/addResourceFile.js +++ b/test/addResourceFile.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), proj = new pbx('.'); function cleanHash() { diff --git a/test/addSourceFile.js b/test/addSourceFile.js index fd5352b..612a0de 100644 --- a/test/addSourceFile.js +++ b/test/addSourceFile.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), proj = new pbx('.'); function cleanHash() { diff --git a/test/addStaticLibrary.js b/test/addStaticLibrary.js index 9b48546..b157a08 100644 --- a/test/addStaticLibrary.js +++ b/test/addStaticLibrary.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), proj = new pbx('.'); function cleanHash() { diff --git a/test/addToPbxFileReferenceSection.js b/test/addToPbxFileReferenceSection.js index da5f440..494f223 100644 --- a/test/addToPbxFileReferenceSection.js +++ b/test/addToPbxFileReferenceSection.js @@ -18,7 +18,7 @@ var jsonProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(jsonProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), myProj = new pbx('.'); function cleanHash() { diff --git a/test/dataModelDocument.js b/test/dataModelDocument.js index c809d62..76477ed 100644 --- a/test/dataModelDocument.js +++ b/test/dataModelDocument.js @@ -19,7 +19,7 @@ var jsonProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(jsonProject), path = require('path'), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), proj = new pbx('.'), singleDataModelFilePath = __dirname + '/fixtures/single-data-model.xcdatamodeld', multipleDataModelFilePath = __dirname + '/fixtures/multiple-data-model.xcdatamodeld'; diff --git a/test/group.js b/test/group.js index 5072aa1..af2454e 100644 --- a/test/group.js +++ b/test/group.js @@ -16,7 +16,7 @@ */ var pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), project, projectHash; diff --git a/test/multipleTargets.js b/test/multipleTargets.js index dc4c419..dbb945f 100644 --- a/test/multipleTargets.js +++ b/test/multipleTargets.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/multiple-targets') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), proj = new pbx('.'); function cleanHash() { diff --git a/test/pbxFile.js b/test/pbxFile.js index f096120..4f0d1a2 100644 --- a/test/pbxFile.js +++ b/test/pbxFile.js @@ -15,7 +15,7 @@ under the License. */ -var pbxFile = require('../lib/pbxFile').pbxFile; +var pbxFile = require('../lib/pbxFile'); exports['lastKnownFileType'] = { 'should detect that a .m path means sourcecode.c.objc': function (test) { diff --git a/test/removeFramework.js b/test/removeFramework.js index 15312d4..20cdbde 100644 --- a/test/removeFramework.js +++ b/test/removeFramework.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project'), fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), proj = new pbx('.'); function cleanHash() { diff --git a/test/removeHeaderFile.js b/test/removeHeaderFile.js index 973533a..358a88a 100644 --- a/test/removeHeaderFile.js +++ b/test/removeHeaderFile.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), proj = new pbx('.'); function cleanHash() { diff --git a/test/removeResourceFile.js b/test/removeResourceFile.js index ca7bb94..f6d6488 100644 --- a/test/removeResourceFile.js +++ b/test/removeResourceFile.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), proj = new pbx('.'); function cleanHash() { diff --git a/test/removeSourceFile.js b/test/removeSourceFile.js index df9f2e7..92fb49b 100644 --- a/test/removeSourceFile.js +++ b/test/removeSourceFile.js @@ -18,7 +18,7 @@ var fullProject = require('./fixtures/full-project') fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), proj = new pbx('.'); function cleanHash() { diff --git a/test/xcode5searchPaths.js b/test/xcode5searchPaths.js index 61014cb..7cdf46c 100644 --- a/test/xcode5searchPaths.js +++ b/test/xcode5searchPaths.js @@ -18,7 +18,7 @@ var xcode5proj = require('./fixtures/library-search-paths') xcode5projStr = JSON.stringify(xcode5proj), pbx = require('../lib/pbxProject'), - pbxFile = require('../lib/pbxFile').pbxFile, + pbxFile = require('../lib/pbxFile'), proj = new pbx('.'), libPoop = { path: 'some/path/poop.a' }; From 8777435705327ae8ba04aef0cb018e2b82bd0de6 Mon Sep 17 00:00:00 2001 From: "Kristian D. Dimitrov" Date: Thu, 21 Mar 2019 10:56:47 +0200 Subject: [PATCH 27/69] fix: modulemap added to ResourcesBuildPhase --- README.md | 2 +- lib/constants.js | 8 +++++++- lib/pbxProject.js | 5 +++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c494f5d..53f9376 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ # --> -# cordova-node-xcode +# nativescript-dev-xcode -[![Build Status](https://travis-ci.org/NativeScript/nativescript-dev-xcode.svg?branch=master)](https://travis-ci.org/apache/cordova-node-xcode) - Parser utility for xcodeproj project files Allows you to edit xcodeproject files and write them back out. @@ -36,19 +31,19 @@ Forked from: [apache/cordova-node-xcode](https://github.com/apache/cordova-node- ```js // API is a bit wonky right now -var xcode = require('xcode'), - fs = require('fs'), - projectPath = 'myproject.xcodeproj/project.pbxproj', - myProj = xcode.project(projectPath); +var xcode = require("xcode"), + fs = require("fs"), + projectPath = "myproject.xcodeproj/project.pbxproj", + myProj = xcode.project(projectPath); // parsing is async, in a different process myProj.parse(function (err) { - myProj.addHeaderFile('foo.h'); - myProj.addSourceFile('foo.m'); - myProj.addFramework('FooKit.framework'); - - fs.writeFileSync(projectPath, myProj.writeSync()); - console.log('new project written'); + myProj.addHeaderFile("foo.h"); + myProj.addSourceFile("foo.m"); + myProj.addFramework("FooKit.framework"); + + fs.writeFileSync(projectPath, myProj.writeSync()); + console.log("new project written"); }); ``` @@ -63,7 +58,9 @@ grammar. Other tests will use the prebuilt parser (`lib/parser/pbxproj.js`). To rebuild the parser js file after editing the grammar, run: - npm run pegjs +``` +npm run pegjs +``` (and be sure to restore the Apache license notice in `lib/parser/pbxproj.js` before committing) diff --git a/package.json b/package.json index 393bffd..25bd532 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ }, "dependencies": { "simple-plist": "1.3.1", - "uuid": "9.0.0" + "uuid": "9.0.1" }, "devDependencies": { "nodeunit": "0.11.3", From 77267e742deb01668fe6bfa35feeb9255ae27e45 Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Fri, 19 Jan 2024 16:47:36 +0100 Subject: [PATCH 52/69] release: 0.6.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 25bd532..e781114 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "name": "nativescript-dev-xcode", "description": "parser for xcodeproj/project.pbxproj files", "main": "index.js", - "version": "0.5.0", + "version": "0.6.0", "files": [ "lib", "!lib/parser/pbxproj.pegjs" From 99947af5ca72755ac59dcf9d458a8a4ee2c8594f Mon Sep 17 00:00:00 2001 From: Jason Cassidy <47318351+jcassidyav@users.noreply.github.com> Date: Tue, 20 Feb 2024 15:11:57 +0000 Subject: [PATCH 53/69] fix: ensure that PbxGroups are not duplicated (#17) --- .gitignore | 2 +- lib/guidMapper.js | 52 ++++++++++++++++++++++++++++++++++ lib/pbxProject.js | 27 +++++++++++++++++- test/guidMapper.js | 69 ++++++++++++++++++++++++++++++++++++++++++++++ test/pbxProject.js | 17 ++++++++++++ 5 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 lib/guidMapper.js create mode 100644 test/guidMapper.js diff --git a/.gitignore b/.gitignore index 0a5bb72..5ef95a1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,5 @@ node_modules/* .DS_Store npm-debug.log package-lock.json - +.ns-build-pbxgroup-data.json *.tgz \ No newline at end of file diff --git a/lib/guidMapper.js b/lib/guidMapper.js new file mode 100644 index 0000000..98300ff --- /dev/null +++ b/lib/guidMapper.js @@ -0,0 +1,52 @@ +const fs = require('fs'); +const path = require('path'); + +function guidMapper(filePath) { + this.filePath = filePath; + this.data = this.loadFromFile(); +} + +guidMapper.prototype.loadFromFile = function () { + try { + const rawData = fs.readFileSync(this.filePath, 'utf8'); + return JSON.parse(rawData); + } catch (error) { + // If file doesn't exist or there's an error parsing it, initialize with an empty object. + return {}; + } +}; + +guidMapper.prototype.writeFileSync = function () { + const jsonData = JSON.stringify(this.data, null, 2); + fs.writeFileSync(this.filePath, jsonData, 'utf8'); +}; + +guidMapper.prototype.addEntry = function (guid, path, name) { + if(!!guid && !! path && !!name){ + this.data[guid] = { path: path, name: name }; + } +}; + +guidMapper.prototype.removeEntry = function (guid) { + if (this.data[guid]) { + delete this.data[guid]; + } +}; + +guidMapper.prototype.getEntries = function () { + return this.data; +}; + +guidMapper.prototype.findEntryGuid = function (name, path) { + for (const guid in this.data) { + if (this.data.hasOwnProperty(guid)) { + const entry = this.data[guid]; + if (entry.path === path && entry.name === name) { + return guid; + } + } + } + return null; +}; + +module.exports = guidMapper; \ No newline at end of file diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 7852427..6364ee3 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -35,7 +35,8 @@ var util = require('util'), isEntitlementFileType = constants.isEntitlementFileType, isAssetFileType = constants.isAssetFileType, isPlistFileType = constants.isPlistFileType, - isModuleMapFileType = constants.isModuleMapFileType; + isModuleMapFileType = constants.isModuleMapFileType, + guidMapper = require('./guidMapper'); function pbxProject(filename) { if (!(this instanceof pbxProject)) @@ -74,6 +75,10 @@ pbxProject.prototype.parseSync = function() { } pbxProject.prototype.writeSync = function(options) { + if(this.pbxGroupTracker){ + this.pbxGroupTracker.writeFileSync(); + } + this.writer = new pbxWriter(this.hash, options); return this.writer.writeSync(); } @@ -538,10 +543,27 @@ pbxProject.prototype.findMainPbxGroup = function () { return null; } +pbxProject.prototype.getPbxGroupTracker = function (path) { + + if(!this.pbxGroupTracker){ + this.pbxGroupTracker = new guidMapper($path.join(path, '.ns-build-pbxgroup-data.json')); + } + + return this.pbxGroupTracker; +} pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceTree, opt) { opt = opt || {}; var srcRootPath = $path.dirname($path.dirname(this.filepath)); + + var existingGroupId = this.getPbxGroupTracker(srcRootPath).findEntryGuid(name, path); + if(existingGroupId){ + if(this.getPBXGroupByKey(existingGroupId)){ + this.removePbxGroupByKey(existingGroupId, path); + } + this.pbxGroupTracker.removeEntry(existingGroupId); + } + var groups = this.hash.project.objects['PBXGroup'], pbxGroupUuid = opt.uuid || this.generateUuid(), commentKey = f("%s_comment", pbxGroupUuid), @@ -560,6 +582,9 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT pbxGroup.path = path; } + // save to group to the tracker + this.pbxGroupTracker.addEntry(pbxGroupUuid, path, name); + for (var key in fileReferenceSection) { // only look for comments if (!COMMENT_KEY.test(key)) continue; diff --git a/test/guidMapper.js b/test/guidMapper.js new file mode 100644 index 0000000..8c9cb72 --- /dev/null +++ b/test/guidMapper.js @@ -0,0 +1,69 @@ +var guidMapper = require('../lib/guidMapper'); +const fs = require('fs'); +const $uuid = require('uuid'); +const TEST_FILE_NAME = 'test/.ns-build-pbxgroup-data.json'; +const goodGUID = $uuid.v4(); +const goodName = "goodName"; +const badName = 'badName'; +const goodPath = "goodPath"; +const badPath = "badPath"; +exports.setUp = function(callback) { + if(fs.existsSync(TEST_FILE_NAME)){ + fs.rmSync(TEST_FILE_NAME); + } + callback(); +} +exports.tearDown = function(callback) { + if(fs.existsSync(TEST_FILE_NAME)){ + fs.rmSync(TEST_FILE_NAME); + } + callback(); +} +function addTestData(){ + var mapper = new guidMapper(TEST_FILE_NAME); + mapper.addEntry(goodGUID, goodPath, goodName); + mapper.writeFileSync(); +} +exports.operations = { + 'should be able to add to map': function(test) { + var mapper = new guidMapper(TEST_FILE_NAME); + mapper.addEntry(goodGUID, goodPath, goodName); + mapper.writeFileSync(); + mapper = new guidMapper(TEST_FILE_NAME); + const result = mapper.findEntryGuid(goodName, goodPath); + + test.ok(result === goodGUID) + test.done(); + }, + 'should not match only on name': function(test) { + addTestData(); + var mapper = new guidMapper(TEST_FILE_NAME); + + const result = mapper.findEntryGuid(goodName, badPath); + + test.ok(result === null) + test.done(); + }, + 'should not match only on path': function(test) { + addTestData(); + var mapper = new guidMapper(TEST_FILE_NAME); + + const result = mapper.findEntryGuid(badName, goodPath); + + test.ok(result === null) + test.done(); + }, + 'can remove': function(test) { + addTestData(); + var mapper = new guidMapper(TEST_FILE_NAME); + mapper.removeEntry(goodGUID); + var result = mapper.findEntryGuid(goodName, goodPath); + + test.ok(result === null); + mapper.writeFileSync(); + result = mapper.findEntryGuid(goodName, goodPath); + test.ok(result === null) + + test.done(); + } +} \ No newline at end of file diff --git a/test/pbxProject.js b/test/pbxProject.js index e846294..860c4f4 100644 --- a/test/pbxProject.js +++ b/test/pbxProject.js @@ -433,3 +433,20 @@ exports['addToPbxFileReferenceSection'] = { } } + +exports['addPbxGroup'] = { + 'should not add the same group twice': function (test) { + var newProj = new pbx('test/parser/projects/group.pbxproj'); + newProj.parse(function (err, hash) { + this.hash.project.objects['PBXVariantGroup']={}; + var group1 = newProj.addPbxGroup(['test/somefile'], "TestGroup", "test/somepath", null, null); + var group2 = newProj.addPbxGroup(['test/somefile'], "TestGroup", "test/somepath", null, null); + test.equal(newProj.getPBXGroupByKey(group1.uuid), null); + test.equal(newProj.getPBXGroupByKey(group2.uuid).name, "TestGroup"); + test.equal(newProj.getPbxGroupTracker().getEntries().hasOwnProperty(group1.uuid), false); + test.equal(newProj.getPbxGroupTracker().getEntries().hasOwnProperty(group2.uuid), true); + + test.done(); + }); + } +} \ No newline at end of file From fef3352ffe3cf0cecbd4b8064d652dab208497aa Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Tue, 20 Feb 2024 16:13:04 +0100 Subject: [PATCH 54/69] release: 0.7.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e781114..5b0cdec 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "name": "nativescript-dev-xcode", "description": "parser for xcodeproj/project.pbxproj files", "main": "index.js", - "version": "0.6.0", + "version": "0.7.0", "files": [ "lib", "!lib/parser/pbxproj.pegjs" From 01236a9a92b9c8bdf404225411603bc18b12ad91 Mon Sep 17 00:00:00 2001 From: farfromrefuge Date: Sat, 6 Jul 2024 03:39:21 +0200 Subject: [PATCH 55/69] fix: symlinks (#18) --- lib/pbxProject.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 6364ee3..bc458de 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -613,7 +613,14 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT if(opt.target) { file.target = opt.target; } - if (fs.existsSync(filePath) && (fs.lstatSync(filePath).isDirectory() || fs.lstatSync(filePath).isSymbolicLink()) && !isAssetFileType(file.lastKnownFileType)) { + // if the file is a symLink, isDirectory() returns false + // but isFile() too so we need to see if the realPath is a directory + const exists = fs.existsSync(filePath); + const stats = exists && fs.lstatSync(filePath); + const isSymlink = exists && fs.lstatSync(filePath).isSymbolicLink(); + let symRealPath = isSymlink && fs.realpathSync(filePath); + const isRealDir = stats && stats.isDirectory() || (isSymlink && fs.lstatSync(symRealPath).isDirectory()); + if (exists && isRealDir && !isAssetFileType(file.lastKnownFileType)) { if($path.extname(filePath) === ".lproj") { continue; } From 36f7c9f4358e79df18a53309181b65b05fdc4767 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Fri, 5 Jul 2024 18:42:42 -0700 Subject: [PATCH 56/69] fix: optional groups when using embedding against host projects --- lib/pbxProject.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index bc458de..1582859 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -2143,7 +2143,7 @@ function correctForFrameworksPath(file, project) { function correctForPath(file, project, group) { var r_group_dir = new RegExp('^' + group + '[\\\\/]'); - if (project.pbxGroupByName(group).path) + if (project.pbxGroupByName(group)?.path) file.path = file.path.replace(r_group_dir, ''); return file; @@ -2393,7 +2393,7 @@ pbxProject.prototype.getPBXGroupByKey = function(key) { }; pbxProject.prototype.getPBXVariantGroupByKey = function(key) { - return this.hash.project.objects['PBXVariantGroup'][key]; + return this.hash.project.objects['PBXVariantGroup']?.[key]; }; From bcb1f9be1af585cbeb349b03d7a805dbae6a664f Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Mon, 8 Jul 2024 14:27:49 -0700 Subject: [PATCH 57/69] fix: add PBXCopyFilesBuildPhase if does not exist --- lib/pbxProject.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 1582859..a6424a5 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -1324,7 +1324,13 @@ pbxProject.prototype.pbxFrameworksBuildPhaseObj = function(target) { } pbxProject.prototype.pbxEmbedFrameworksBuildPhaseObj = function (target) { - return this.buildPhaseObject('PBXCopyFilesBuildPhase', 'Embed Frameworks', target); + let buildPhase = this.buildPhaseObject('PBXCopyFilesBuildPhase', 'Embed Frameworks', target); + if (!buildPhase) { + // Create CopyFiles phase in parent target + const phase = this.addBuildPhase([], 'PBXCopyFilesBuildPhase', 'Embed Frameworks', target); + buildPhase = phase.buildPhase; + } + return buildPhase; }; // Find Build Phase from group/target From 4b846bbe6907210d9bc0c39c35f409df77d923bd Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Mon, 8 Jul 2024 14:28:02 -0700 Subject: [PATCH 58/69] release: 0.7.1-alpha.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5b0cdec..774be68 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "name": "nativescript-dev-xcode", "description": "parser for xcodeproj/project.pbxproj files", "main": "index.js", - "version": "0.7.0", + "version": "0.7.1-alpha.1", "files": [ "lib", "!lib/parser/pbxproj.pegjs" From a1fbeca0d787c8179aaef79d00cb1b4a3f2d62a2 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Mon, 8 Jul 2024 21:02:56 -0700 Subject: [PATCH 59/69] fix: add PBXFrameworksBuildPhase if does not exist --- lib/pbxProject.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index a6424a5..234590d 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -1320,7 +1320,13 @@ pbxProject.prototype.pbxResourcesBuildPhaseObj = function(target) { } pbxProject.prototype.pbxFrameworksBuildPhaseObj = function(target) { - return this.buildPhaseObject('PBXFrameworksBuildPhase', 'Frameworks', target); + let buildPhase = this.buildPhaseObject('PBXFrameworksBuildPhase', 'Frameworks', target); + if (!buildPhase) { + // Create Frameworks phase in parent target + const phase = this.addBuildPhase([], 'PBXFrameworksBuildPhase', 'Frameworks', target); + buildPhase = phase.buildPhase; + } + return buildPhase; } pbxProject.prototype.pbxEmbedFrameworksBuildPhaseObj = function (target) { From 3dec27ce4497fbfd73e419ffa5cefb70a096f006 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Mon, 8 Jul 2024 21:03:20 -0700 Subject: [PATCH 60/69] release: 0.7.1-alpha.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 774be68..024684b 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "name": "nativescript-dev-xcode", "description": "parser for xcodeproj/project.pbxproj files", "main": "index.js", - "version": "0.7.1-alpha.1", + "version": "0.7.1-alpha.2", "files": [ "lib", "!lib/parser/pbxproj.pegjs" From 4b8ef6e8a5e38c73c765d6c9a2e7bcb7632b5751 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Mon, 8 Jul 2024 21:24:51 -0700 Subject: [PATCH 61/69] fix: ensure frameworks are added to destination type 'frameworks' on build --- lib/pbxProject.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 234590d..fdc3f38 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -1323,7 +1323,7 @@ pbxProject.prototype.pbxFrameworksBuildPhaseObj = function(target) { let buildPhase = this.buildPhaseObject('PBXFrameworksBuildPhase', 'Frameworks', target); if (!buildPhase) { // Create Frameworks phase in parent target - const phase = this.addBuildPhase([], 'PBXFrameworksBuildPhase', 'Frameworks', target); + const phase = this.addBuildPhase([], 'PBXFrameworksBuildPhase', 'Frameworks', target, 'frameworks'); buildPhase = phase.buildPhase; } return buildPhase; @@ -1333,7 +1333,7 @@ pbxProject.prototype.pbxEmbedFrameworksBuildPhaseObj = function (target) { let buildPhase = this.buildPhaseObject('PBXCopyFilesBuildPhase', 'Embed Frameworks', target); if (!buildPhase) { // Create CopyFiles phase in parent target - const phase = this.addBuildPhase([], 'PBXCopyFilesBuildPhase', 'Embed Frameworks', target); + const phase = this.addBuildPhase([], 'PBXCopyFilesBuildPhase', 'Embed Frameworks', target, 'frameworks'); buildPhase = phase.buildPhase; } return buildPhase; From 19adee4e00942be272f4caa8494aef82a9b13559 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Mon, 8 Jul 2024 21:25:37 -0700 Subject: [PATCH 62/69] release: 0.7.1-alpha.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 024684b..2731a34 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "name": "nativescript-dev-xcode", "description": "parser for xcodeproj/project.pbxproj files", "main": "index.js", - "version": "0.7.1-alpha.2", + "version": "0.7.1-alpha.3", "files": [ "lib", "!lib/parser/pbxproj.pegjs" From 8f7639fb2b65cddedd6e88af2b552478a841d076 Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Tue, 9 Jul 2024 16:53:35 +0200 Subject: [PATCH 63/69] fix: only set PBXGroup path when defined --- lib/pbxProject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index fdc3f38..2f31cf2 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -578,7 +578,7 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT filePathToReference = {}; //path is mandatory only for the main group - if(!opt.filesRelativeToProject) { + if(!opt.filesRelativeToProject && path) { pbxGroup.path = path; } From 99be00ff24b269d93d2cdd5637827a4ec7ebd118 Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Tue, 9 Jul 2024 16:53:51 +0200 Subject: [PATCH 64/69] fix: don't add duplicate HEADER_SEARCH_PATHS --- lib/pbxProject.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 2f31cf2..1379e04 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -1566,7 +1566,11 @@ pbxProject.prototype.addToHeaderSearchPaths = function(file, productName) { buildSettings['HEADER_SEARCH_PATHS'] = [INHERITED]; } - buildSettings['HEADER_SEARCH_PATHS'].push(searchPathForFile(file, this)); + // Check if the search path is already in the HEADER_SEARCH_PATHS and add it if it's not. + const searchPath = searchPathForFile(file, this); + if (buildSettings['HEADER_SEARCH_PATHS'].indexOf(searchPath) < 0) { + buildSettings['HEADER_SEARCH_PATHS'].push(searchPath); + } } } From 5512dcc033628d22cd41164131a01ef2b1ae2263 Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Tue, 9 Jul 2024 16:54:27 +0200 Subject: [PATCH 65/69] fix: make sure Frameworks is a main group (so it's visible in xcode sidebar) --- lib/pbxProject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 1379e04..b45e1be 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -885,7 +885,7 @@ pbxProject.prototype.removeFromResourcesPbxGroup = function(file) { pbxProject.prototype.addToFrameworksPbxGroup = function(file) { var pluginsGroup = this.pbxGroupByName('Frameworks'); if (!pluginsGroup) { - this.addPbxGroup([file.path], 'Frameworks'); + this.addPbxGroup([file.path], 'Frameworks', 'Frameworks', null, { isMain: true, filesRelativeToProject: true}); } else { pluginsGroup.children.push(pbxGroupChild(file)); } From 01f1563acaae85634508b957700524b8e200003f Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Tue, 9 Jul 2024 09:11:37 -0700 Subject: [PATCH 66/69] release: 0.7.1-alpha.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2731a34..a6d5785 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "name": "nativescript-dev-xcode", "description": "parser for xcodeproj/project.pbxproj files", "main": "index.js", - "version": "0.7.1-alpha.3", + "version": "0.7.1-alpha.4", "files": [ "lib", "!lib/parser/pbxproj.pegjs" From 8f96af8e71274570eea6369a7723f67406a67b5c Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Thu, 11 Jul 2024 16:46:53 +0200 Subject: [PATCH 67/69] release: 0.8.0 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index a6d5785..88f2554 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "name": "nativescript-dev-xcode", "description": "parser for xcodeproj/project.pbxproj files", "main": "index.js", - "version": "0.7.1-alpha.4", + "version": "0.8.0", "files": [ "lib", "!lib/parser/pbxproj.pegjs" @@ -12,7 +12,7 @@ "url": "https://github.com/NativeScript/nativescript-dev-xcode.git" }, "engines": { - "node": ">=6.0.0" + "node": ">=14.0.0" }, "dependencies": { "simple-plist": "1.3.1", From bf41b1d06b951dab4400bb5f267c7a47cb4cf73e Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Wed, 19 Feb 2025 19:45:06 -0800 Subject: [PATCH 68/69] fix: when removing targets with projects including widgets, ref may not be found This case can be safely ignored to prevent a cli hard exit --- lib/pbxProject.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/pbxProject.js b/lib/pbxProject.js index b45e1be..70f82ea 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -1855,10 +1855,13 @@ pbxProject.prototype.removeTarget = function(target, targetKey) { if(!stillReferenced) { var frameworkFileRef = fileReferenceSection[fileRef]; - var fileToRemove = new pbxFile(unquote(frameworkFileRef.path), {basename: frameworkFileRef.name}); - fileToRemove.fileRef = fileRef; - this.removeFromFrameworksPbxGroup(fileToRemove); - removeItemAndCommentFromSectionByUuid(fileReferenceSection, fileRef); + if (frameworkFileRef?.path) { + // when working with widgets, the framework might be in a different group + var fileToRemove = new pbxFile(unquote(frameworkFileRef.path), {basename: frameworkFileRef.name}); + fileToRemove.fileRef = fileRef; + this.removeFromFrameworksPbxGroup(fileToRemove); + removeItemAndCommentFromSectionByUuid(fileReferenceSection, fileRef); + } } } files = files.concat(frameworkFiles); From 748f1801e58159a5233b60046b9f566873bf76db Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Wed, 19 Feb 2025 19:45:22 -0800 Subject: [PATCH 69/69] release: 0.8.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 88f2554..69b2110 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "name": "nativescript-dev-xcode", "description": "parser for xcodeproj/project.pbxproj files", "main": "index.js", - "version": "0.8.0", + "version": "0.8.1", "files": [ "lib", "!lib/parser/pbxproj.pegjs"