diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..65e3ba2 --- /dev/null +++ b/.npmignore @@ -0,0 +1 @@ +test/ diff --git a/LICENSE b/LICENSE index 45f03a3..d645695 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,193 @@ - Copyright 2012 Andrew Lunny, Adobe Systems + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -11,4 +200,3 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - diff --git a/README.md b/README.md index 32582da..34a9013 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,17 @@ + + +# This project has been contributed to the Apache Cordova project and will be maintained in its new home there. Please update your upstreams, forks, and pull requests + +- cordova-node-xcode [`https://github.com/apache/cordova-node-xcode.git`](https://github.com/apache/cordova-node-xcode.git) + +- Apache Cordova [`https://cordova.apache.org`](https://cordova.apache.org) + + + + +--- + + # node-xcode > parser/toolkit for xcodeproj project files @@ -17,11 +31,26 @@ Allows you to edit xcodeproject files and write them back out. myProj.addHeaderFile('foo.h'); myProj.addSourceFile('foo.m'); myProj.addFramework('FooKit.framework'); - + fs.writeFileSync(projectPath, myProj.writeSync()); console.log('new project written'); }); +## Working on the parser + +If there's a problem parsing, you will want to edit the grammar under +`lib/parser/pbxproj.pegjs`. You can test it online with the PEGjs online thingy +at http://pegjs.majda.cz/online - I have had some mixed results though. + +Tests under the `test/parser` directory will compile the parser from the +grammar. Other tests will use the prebuilt parser (`lib/parser/pbxproj.js`). + +To rebuild the parser js file after editing the grammar, run: + + ./node_modules/.bin/pegjs lib/parser/pbxproj.pegjs + +(easier if `./node_modules/.bin` is in your path) + ## License -MIT +Apache V2 diff --git a/lib/parseJob.js b/lib/parseJob.js index 804be10..9d6bffa 100644 --- a/lib/parseJob.js +++ b/lib/parseJob.js @@ -6,11 +6,10 @@ var fs = require('fs'), fileContents, obj; try { - fileContents = fs.readFileSync(path, 'utf-8'), - obj = parser.parse(fileContents) - process.send(obj) - process.exit() + fileContents = fs.readFileSync(path, 'utf-8'); + obj = parser.parse(fileContents); + process.send(obj); } catch (e) { - process.send(e) - process.exit(1) + process.send(e); + process.exitCode = 1; } diff --git a/lib/parser/pbxproj.js b/lib/parser/pbxproj.js index c56ace3..69f2a6a 100644 --- a/lib/parser/pbxproj.js +++ b/lib/parser/pbxproj.js @@ -1,2659 +1,1899 @@ -module.exports = (function(){ - /* Generated by PEG.js 0.6.2 (http://pegjs.majda.cz/). */ - - var result = { - /* - * Parses the input with a generated parser. If the parsing is successfull, - * returns a value explicitly or implicitly specified by the grammar from - * which the parser was generated (see |PEG.buildParser|). If the parsing is - * unsuccessful, throws |PEG.parser.SyntaxError| describing the error. - */ - parse: function(input, startRule) { - var parseFunctions = { - "Alpha": parse_Alpha, - "Array": parse_Array, - "ArrayBody": parse_ArrayBody, - "ArrayEntry": parse_ArrayEntry, - "Assignment": parse_Assignment, - "AssignmentList": parse_AssignmentList, - "Char": parse_Char, - "CommentedArrayEntry": parse_CommentedArrayEntry, - "CommentedAssignment": parse_CommentedAssignment, - "CommentedIdentifier": parse_CommentedIdentifier, - "CommentedValue": parse_CommentedValue, - "DecimalValue": parse_DecimalValue, - "DelimitedSection": parse_DelimitedSection, - "DelimitedSectionBegin": parse_DelimitedSectionBegin, - "DelimitedSectionEnd": parse_DelimitedSectionEnd, - "Digit": parse_Digit, - "DoubleQuote": parse_DoubleQuote, - "EmptyArray": parse_EmptyArray, - "EmptyBody": parse_EmptyBody, - "EscapedQuote": parse_EscapedQuote, - "Identifier": parse_Identifier, - "InlineComment": parse_InlineComment, - "InlineCommentClose": parse_InlineCommentClose, - "InlineCommentOpen": parse_InlineCommentOpen, - "IntegerValue": parse_IntegerValue, - "LineTerminator": parse_LineTerminator, - "LiteralChar": parse_LiteralChar, - "LiteralString": parse_LiteralString, - "NewLine": parse_NewLine, - "NonLine": parse_NonLine, - "NonQuote": parse_NonQuote, - "NumberValue": parse_NumberValue, - "Object": parse_Object, - "OneLineString": parse_OneLineString, - "Project": parse_Project, - "QuotedBody": parse_QuotedBody, - "QuotedString": parse_QuotedString, - "SimpleArrayEntry": parse_SimpleArrayEntry, - "SimpleAssignment": parse_SimpleAssignment, - "SingleLineComment": parse_SingleLineComment, - "StringValue": parse_StringValue, - "Value": parse_Value, - "_": parse__, - "whitespace": parse_whitespace +/* + * Generated by PEG.js 0.10.0. + * + * http://pegjs.org/ + */ + +"use strict"; + +function peg$subclass(child, parent) { + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); +} + +function peg$SyntaxError(message, expected, found, location) { + this.message = message; + this.expected = expected; + this.found = found; + this.location = location; + this.name = "SyntaxError"; + + if (typeof Error.captureStackTrace === "function") { + Error.captureStackTrace(this, peg$SyntaxError); + } +} + +peg$subclass(peg$SyntaxError, Error); + +peg$SyntaxError.buildMessage = function(expected, found) { + var DESCRIBE_EXPECTATION_FNS = { + literal: function(expectation) { + return "\"" + literalEscape(expectation.text) + "\""; + }, + + "class": function(expectation) { + var escapedParts = "", + i; + + for (i = 0; i < expectation.parts.length; i++) { + escapedParts += expectation.parts[i] instanceof Array + ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1]) + : classEscape(expectation.parts[i]); + } + + return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]"; + }, + + any: function(expectation) { + return "any character"; + }, + + end: function(expectation) { + return "end of input"; + }, + + other: function(expectation) { + return expectation.description; + } }; - - if (startRule !== undefined) { - if (parseFunctions[startRule] === undefined) { - throw new Error("Invalid rule name: " + quote(startRule) + "."); + + function hex(ch) { + return ch.charCodeAt(0).toString(16).toUpperCase(); + } + + function literalEscape(s) { + return s + .replace(/\\/g, '\\\\') + .replace(/"/g, '\\"') + .replace(/\0/g, '\\0') + .replace(/\t/g, '\\t') + .replace(/\n/g, '\\n') + .replace(/\r/g, '\\r') + .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); + } + + function classEscape(s) { + return s + .replace(/\\/g, '\\\\') + .replace(/\]/g, '\\]') + .replace(/\^/g, '\\^') + .replace(/-/g, '\\-') + .replace(/\0/g, '\\0') + .replace(/\t/g, '\\t') + .replace(/\n/g, '\\n') + .replace(/\r/g, '\\r') + .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); + } + + function describeExpectation(expectation) { + return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); + } + + function describeExpected(expected) { + var descriptions = new Array(expected.length), + i, j; + + for (i = 0; i < expected.length; i++) { + descriptions[i] = describeExpectation(expected[i]); + } + + descriptions.sort(); + + if (descriptions.length > 0) { + for (i = 1, j = 1; i < descriptions.length; i++) { + if (descriptions[i - 1] !== descriptions[i]) { + descriptions[j] = descriptions[i]; + j++; } - } else { - startRule = "Project"; } - - var pos = 0; - var reportMatchFailures = true; - var rightmostMatchFailuresPos = 0; - var rightmostMatchFailuresExpected = []; - var cache = {}; - - function padLeft(input, padding, length) { - var result = input; - - var padLength = length - input.length; - for (var i = 0; i < padLength; i++) { - result = padding + result; - } - - return result; + descriptions.length = j; + } + + switch (descriptions.length) { + case 1: + return descriptions[0]; + + case 2: + return descriptions[0] + " or " + descriptions[1]; + + default: + return descriptions.slice(0, -1).join(", ") + + ", or " + + descriptions[descriptions.length - 1]; + } + } + + function describeFound(found) { + return found ? "\"" + literalEscape(found) + "\"" : "end of input"; + } + + return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; +}; + +function peg$parse(input, options) { + options = options !== void 0 ? options : {}; + + var peg$FAILED = {}, + + peg$startRuleFunctions = { Project: peg$parseProject }, + peg$startRuleFunction = peg$parseProject, + + peg$c0 = function(headComment, obj) { + var proj = Object.create(null) + proj.project = obj + + if (headComment) { + proj.headComment = headComment + } + + return proj; + }, + peg$c1 = "{", + peg$c2 = peg$literalExpectation("{", false), + peg$c3 = "}", + peg$c4 = peg$literalExpectation("}", false), + peg$c5 = function(obj) { return obj }, + peg$c6 = function() { return Object.create(null) }, + peg$c7 = function(list) { + var returnObject = list[0][0]; + for(var i = 1; i < list.length; i++){ + var another = list[i][0]; + returnObject = merge_obj(returnObject, another); + } + return returnObject; + }, + peg$c8 = "=", + peg$c9 = peg$literalExpectation("=", false), + peg$c10 = ";", + peg$c11 = peg$literalExpectation(";", false), + peg$c12 = function(id, val) { + var result = Object.create(null); + result[id] = val + return result + }, + peg$c13 = function(commentedId, val) { + var result = Object.create(null), + commentKey = commentedId.id + '_comment'; + + result[commentedId.id] = val; + result[commentKey] = commentedId[commentKey]; + return result; + + }, + peg$c14 = function(id, commentedVal) { + var result = Object.create(null); + result[id] = commentedVal.value; + result[id + "_comment"] = commentedVal.comment; + return result; + }, + peg$c15 = function(id, comment) { + var result = Object.create(null); + result.id = id; + result[id + "_comment"] = comment.trim(); + return result + }, + peg$c16 = function(literal, comment) { + var result = Object.create(null) + result.comment = comment.trim(); + result.value = literal.trim(); + return result; + }, + peg$c17 = /^[^*]/, + peg$c18 = peg$classExpectation(["*"], true, false), + peg$c19 = function(body) { return body.join('') }, + peg$c20 = "/*", + peg$c21 = peg$literalExpectation("/*", false), + peg$c22 = "*/", + peg$c23 = peg$literalExpectation("*/", false), + peg$c24 = function(begin, fields) { + var section = Object.create(null); + section[begin.name] = fields + + return section + }, + peg$c25 = "/* Begin ", + peg$c26 = peg$literalExpectation("/* Begin ", false), + peg$c27 = " section */", + peg$c28 = peg$literalExpectation(" section */", false), + peg$c29 = function(sectionName) { return { name: sectionName } }, + peg$c30 = "/* End ", + peg$c31 = peg$literalExpectation("/* End ", false), + peg$c32 = "(", + peg$c33 = peg$literalExpectation("(", false), + peg$c34 = ")", + peg$c35 = peg$literalExpectation(")", false), + peg$c36 = function(arr) { return arr }, + peg$c37 = function() { return [] }, + peg$c38 = function(head, tail) { + if (tail) { + tail.unshift(head); + return tail; + } else { + return [head]; + } + }, + peg$c39 = function(val) { return val }, + peg$c40 = function(val, comment) { + var result = Object.create(null); + result.value = val.trim(); + result.comment = comment.trim(); + return result; + }, + peg$c41 = ",", + peg$c42 = peg$literalExpectation(",", false), + peg$c43 = /^[A-Za-z0-9_.]/, + peg$c44 = peg$classExpectation([["A", "Z"], ["a", "z"], ["0", "9"], "_", "."], false, false), + peg$c45 = function(id) { return id.join('') }, + peg$c46 = ".", + peg$c47 = peg$literalExpectation(".", false), + peg$c48 = function(decimal) { + // store decimals as strings + // as JS doesn't differentiate bw strings and numbers + return decimal.join('') + }, + peg$c49 = function(number) { return parseInt(number.join(''), 10) }, + peg$c50 = function(str) { return '"' + str + '"' }, + peg$c51 = function(str) { return str.join('') }, + peg$c52 = peg$anyExpectation(), + peg$c53 = function(char) { return char }, + peg$c54 = "\\", + peg$c55 = peg$literalExpectation("\\", false), + peg$c56 = function() { return '\\"' }, + peg$c57 = function(literal) { return literal.join('') }, + peg$c58 = /^[^;,\n]/, + peg$c59 = peg$classExpectation([";", ",", "\n"], true, false), + peg$c60 = "//", + peg$c61 = peg$literalExpectation("//", false), + peg$c62 = function(contents) { return contents }, + peg$c63 = function(contents) { return contents.join('') }, + peg$c64 = /^[0-9]/, + peg$c65 = peg$classExpectation([["0", "9"]], false, false), + peg$c66 = /^[A-Za-z]/, + peg$c67 = peg$classExpectation([["A", "Z"], ["a", "z"]], false, false), + peg$c68 = "\"", + peg$c69 = peg$literalExpectation("\"", false), + peg$c70 = peg$otherExpectation("whitespace"), + peg$c71 = /^[\t ]/, + peg$c72 = peg$classExpectation(["\t", " "], false, false), + peg$c73 = /^[\n\r]/, + peg$c74 = peg$classExpectation(["\n", "\r"], false, false), + + peg$currPos = 0, + peg$savedPos = 0, + peg$posDetailsCache = [{ line: 1, column: 1 }], + peg$maxFailPos = 0, + peg$maxFailExpected = [], + peg$silentFails = 0, + + peg$result; + + if ("startRule" in options) { + if (!(options.startRule in peg$startRuleFunctions)) { + throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); + } + + peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; + } + + function text() { + return input.substring(peg$savedPos, peg$currPos); + } + + function location() { + return peg$computeLocation(peg$savedPos, peg$currPos); + } + + function expected(description, location) { + location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos) + + throw peg$buildStructuredError( + [peg$otherExpectation(description)], + input.substring(peg$savedPos, peg$currPos), + location + ); + } + + function error(message, location) { + location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos) + + throw peg$buildSimpleError(message, location); + } + + function peg$literalExpectation(text, ignoreCase) { + return { type: "literal", text: text, ignoreCase: ignoreCase }; + } + + function peg$classExpectation(parts, inverted, ignoreCase) { + return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; + } + + function peg$anyExpectation() { + return { type: "any" }; + } + + function peg$endExpectation() { + return { type: "end" }; + } + + function peg$otherExpectation(description) { + return { type: "other", description: description }; + } + + function peg$computePosDetails(pos) { + var details = peg$posDetailsCache[pos], p; + + if (details) { + return details; + } else { + p = pos - 1; + while (!peg$posDetailsCache[p]) { + p--; } - - function escape(ch) { - var charCode = ch.charCodeAt(0); - - if (charCode <= 0xFF) { - var escapeChar = 'x'; - var length = 2; + + details = peg$posDetailsCache[p]; + details = { + line: details.line, + column: details.column + }; + + while (p < pos) { + if (input.charCodeAt(p) === 10) { + details.line++; + details.column = 1; } else { - var escapeChar = 'u'; - var length = 4; + details.column++; } - - return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length); + + p++; } - - function quote(s) { - /* - * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a - * string literal except for the closing quote character, backslash, - * carriage return, line separator, paragraph separator, and line feed. - * Any character may appear in the form of an escape sequence. - */ - return '"' + s - .replace(/\\/g, '\\\\') // backslash - .replace(/"/g, '\\"') // closing quote character - .replace(/\r/g, '\\r') // carriage return - .replace(/\n/g, '\\n') // line feed - .replace(/[\x80-\uFFFF]/g, escape) // non-ASCII characters - + '"'; + + peg$posDetailsCache[pos] = details; + return details; + } + } + + function peg$computeLocation(startPos, endPos) { + var startPosDetails = peg$computePosDetails(startPos), + endPosDetails = peg$computePosDetails(endPos); + + return { + start: { + offset: startPos, + line: startPosDetails.line, + column: startPosDetails.column + }, + end: { + offset: endPos, + line: endPosDetails.line, + column: endPosDetails.column } - - function matchFailed(failure) { - if (pos < rightmostMatchFailuresPos) { - return; - } - - if (pos > rightmostMatchFailuresPos) { - rightmostMatchFailuresPos = pos; - rightmostMatchFailuresExpected = []; - } - - rightmostMatchFailuresExpected.push(failure); + }; + } + + function peg$fail(expected) { + if (peg$currPos < peg$maxFailPos) { return; } + + if (peg$currPos > peg$maxFailPos) { + peg$maxFailPos = peg$currPos; + peg$maxFailExpected = []; + } + + peg$maxFailExpected.push(expected); + } + + function peg$buildSimpleError(message, location) { + return new peg$SyntaxError(message, null, null, location); + } + + function peg$buildStructuredError(expected, found, location) { + return new peg$SyntaxError( + peg$SyntaxError.buildMessage(expected, found), + expected, + found, + location + ); + } + + function peg$parseProject() { + var s0, s1, s2, s3, s4, s5, s6; + + s0 = peg$currPos; + s1 = peg$parseSingleLineComment(); + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + s2 = peg$parseInlineComment(); + if (s2 === peg$FAILED) { + s2 = null; } - - function parse_Project() { - var cacheKey = 'Project@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - var result10 = parse_SingleLineComment(); - var result3 = result10 !== null ? result10 : ''; - if (result3 !== null) { - var result9 = parse_InlineComment(); - var result4 = result9 !== null ? result9 : ''; - if (result4 !== null) { - var result5 = parse__(); - if (result5 !== null) { - var result6 = parse_Object(); - if (result6 !== null) { - var result7 = parse_NewLine(); - if (result7 !== null) { - var result8 = parse__(); - if (result8 !== null) { - var result1 = [result3, result4, result5, result6, result7, result8]; - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + s4 = peg$parseObject(); + if (s4 !== peg$FAILED) { + s5 = peg$parseNewLine(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c0(s1, s4); + s0 = s1; } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result1 = null; - pos = savedPos1; - } - var result2 = result1 !== null - ? (function(headComment, obj) { - var proj = Object.create(null) - proj.project = obj - - if (headComment) { - proj.headComment = headComment - } - - return proj; - })(result1[0], result1[3]) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; + peg$currPos = s0; + s0 = peg$FAILED; } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_Object() { - var cacheKey = 'Object@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - if (input.substr(pos, 1) === "{") { - var result3 = "{"; - pos += 1; - } else { - var result3 = null; - if (reportMatchFailures) { - matchFailed("\"{\""); - } - } - if (result3 !== null) { - var result7 = parse_AssignmentList(); - if (result7 !== null) { - var result4 = result7; - } else { - var result6 = parse_EmptyBody(); - if (result6 !== null) { - var result4 = result6; - } else { - var result4 = null;; - }; - } - if (result4 !== null) { - if (input.substr(pos, 1) === "}") { - var result5 = "}"; - pos += 1; - } else { - var result5 = null; - if (reportMatchFailures) { - matchFailed("\"}\""); - } - } - if (result5 !== null) { - var result1 = [result3, result4, result5]; - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseObject() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 123) { + s1 = peg$c1; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c2); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseAssignmentList(); + if (s2 === peg$FAILED) { + s2 = peg$parseEmptyBody(); + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 125) { + s3 = peg$c3; + peg$currPos++; } else { - var result1 = null; - pos = savedPos1; + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c4); } } - var result2 = result1 !== null - ? (function(obj) { return obj })(result1[1]) - : null; - if (result2 !== null) { - var result0 = result2; + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c5(s2); + s0 = s1; } else { - var result0 = null; - pos = savedPos0; + peg$currPos = s0; + s0 = peg$FAILED; } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_EmptyBody() { - var cacheKey = 'EmptyBody@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var result1 = parse__(); - var result2 = result1 !== null - ? (function() { return Object.create(null) })() - : null; - if (result2 !== null) { - var result0 = result2; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseEmptyBody() { + var s0, s1; + + s0 = peg$currPos; + s1 = peg$parse_(); + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c6(); + } + s0 = s1; + + return s0; + } + + function peg$parseAssignmentList() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parse_(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parseAssignment(); + if (s4 === peg$FAILED) { + s4 = peg$parseDelimitedSection(); + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s4 = [s4, s5]; + s3 = s4; } else { - var result0 = null; - pos = savedPos0; + peg$currPos = s3; + s3 = peg$FAILED; } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s3; + s3 = peg$FAILED; } - - function parse_AssignmentList() { - var cacheKey = 'AssignmentList@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos2 = pos; - var savedPos3 = pos; - var result12 = parse__(); - if (result12 !== null) { - var result13 = parse_Assignment(); - if (result13 !== null) { - var result14 = parse__(); - if (result14 !== null) { - var result15 = []; - var result17 = parse_AssignmentList(); - while (result17 !== null) { - result15.push(result17); - var result17 = parse_AssignmentList(); - } - if (result15 !== null) { - var result16 = parse__(); - if (result16 !== null) { - var result10 = [result12, result13, result14, result15, result16]; - } else { - var result10 = null; - pos = savedPos3; - } - } else { - var result10 = null; - pos = savedPos3; - } - } else { - var result10 = null; - pos = savedPos3; - } - } else { - var result10 = null; - pos = savedPos3; + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parseAssignment(); + if (s4 === peg$FAILED) { + s4 = peg$parseDelimitedSection(); } - } else { - var result10 = null; - pos = savedPos3; - } - var result11 = result10 !== null - ? (function(head, tail) { - if (tail) return merge(head,tail) - else return head - })(result10[1], result10[3]) - : null; - if (result11 !== null) { - var result9 = result11; - } else { - var result9 = null; - pos = savedPos2; - } - if (result9 !== null) { - var result0 = result9; - } else { - var savedPos0 = pos; - var savedPos1 = pos; - var result4 = parse__(); - if (result4 !== null) { - var result5 = parse_DelimitedSection(); - if (result5 !== null) { - var result6 = parse__(); - if (result6 !== null) { - var result7 = []; - var result8 = parse_AssignmentList(); - while (result8 !== null) { - result7.push(result8); - var result8 = parse_AssignmentList(); - } - if (result7 !== null) { - var result2 = [result4, result5, result6, result7]; - } else { - var result2 = null; - pos = savedPos1; - } - } else { - var result2 = null; - pos = savedPos1; - } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s4 = [s4, s5]; + s3 = s4; } else { - var result2 = null; - pos = savedPos1; + peg$currPos = s3; + s3 = peg$FAILED; } } else { - var result2 = null; - pos = savedPos1; + peg$currPos = s3; + s3 = peg$FAILED; } - var result3 = result2 !== null - ? (function(head, tail) { - if (tail) return merge(head,tail) - else return head - })(result2[1], result2[3]) - : null; - if (result3 !== null) { - var result1 = result3; - } else { - var result1 = null; - pos = savedPos0; - } - if (result1 !== null) { - var result0 = result1; - } else { - var result0 = null;; - }; } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + s2 = peg$FAILED; } - - function parse_Assignment() { - var cacheKey = 'Assignment@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var result2 = parse_SimpleAssignment(); - if (result2 !== null) { - var result0 = result2; - } else { - var result1 = parse_CommentedAssignment(); - if (result1 !== null) { - var result0 = result1; - } else { - var result0 = null;; - }; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c7(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_SimpleAssignment() { - var cacheKey = 'SimpleAssignment@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - var result3 = parse_Identifier(); - if (result3 !== null) { - var result4 = parse__(); - if (result4 !== null) { - if (input.substr(pos, 1) === "=") { - var result5 = "="; - pos += 1; - } else { - var result5 = null; - if (reportMatchFailures) { - matchFailed("\"=\""); - } - } - if (result5 !== null) { - var result6 = parse__(); - if (result6 !== null) { - var result7 = parse_Value(); - if (result7 !== null) { - if (input.substr(pos, 1) === ";") { - var result8 = ";"; - pos += 1; - } else { - var result8 = null; - if (reportMatchFailures) { - matchFailed("\";\""); - } - } - if (result8 !== null) { - var result1 = [result3, result4, result5, result6, result7, result8]; - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseAssignment() { + var s0; + + s0 = peg$parseSimpleAssignment(); + if (s0 === peg$FAILED) { + s0 = peg$parseCommentedAssignment(); + } + + return s0; + } + + function peg$parseSimpleAssignment() { + var s0, s1, s2, s3, s4, s5, s6; + + s0 = peg$currPos; + s1 = peg$parseIdentifier(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 61) { + s3 = peg$c8; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c9); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseValue(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 59) { + s6 = peg$c10; + peg$currPos++; } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - var result2 = result1 !== null - ? (function(id, val) { - var result = Object.create(null); - result[id] = val - return result - })(result1[0], result1[4]) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; - } - - function parse_CommentedAssignment() { - var cacheKey = 'CommentedAssignment@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos2 = pos; - var savedPos3 = pos; - var result13 = parse_CommentedIdentifier(); - if (result13 !== null) { - var result14 = parse__(); - if (result14 !== null) { - if (input.substr(pos, 1) === "=") { - var result15 = "="; - pos += 1; - } else { - var result15 = null; - if (reportMatchFailures) { - matchFailed("\"=\""); + s6 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c11); } } - } - if (result15 !== null) { - var result16 = parse__(); - if (result16 !== null) { - var result17 = parse_Value(); - if (result17 !== null) { - if (input.substr(pos, 1) === ";") { - var result18 = ";"; - pos += 1; - } else { - var result18 = null; - if (reportMatchFailures) { - matchFailed("\";\""); - } - } - if (result18 !== null) { - var result11 = [result13, result14, result15, result16, result17, result18]; - } else { - var result11 = null; - pos = savedPos3; - } - } else { - var result11 = null; - pos = savedPos3; - } + if (s6 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c12(s1, s5); + s0 = s1; } else { - var result11 = null; - pos = savedPos3; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result11 = null; - pos = savedPos3; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result11 = null; - pos = savedPos3; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result11 = null; - pos = savedPos3; + peg$currPos = s0; + s0 = peg$FAILED; } - var result12 = result11 !== null - ? (function(commentedId, val) { - var result = Object.create(null), - commentKey = commentedId.id + '_comment'; - - result[commentedId.id] = val; - result[commentKey] = commentedId[commentKey]; - return result; - - })(result11[0], result11[4]) - : null; - if (result12 !== null) { - var result10 = result12; - } else { - var result10 = null; - pos = savedPos2; - } - if (result10 !== null) { - var result0 = result10; - } else { - var savedPos0 = pos; - var savedPos1 = pos; - var result4 = parse_Identifier(); - if (result4 !== null) { - var result5 = parse__(); - if (result5 !== null) { - if (input.substr(pos, 1) === "=") { - var result6 = "="; - pos += 1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseCommentedAssignment() { + var s0, s1, s2, s3, s4, s5, s6; + + s0 = peg$currPos; + s1 = peg$parseCommentedIdentifier(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 61) { + s3 = peg$c8; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c9); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseValue(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 59) { + s6 = peg$c10; + peg$currPos++; } else { - var result6 = null; - if (reportMatchFailures) { - matchFailed("\"=\""); - } + s6 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c11); } } - if (result6 !== null) { - var result7 = parse__(); - if (result7 !== null) { - var result8 = parse_CommentedValue(); - if (result8 !== null) { - if (input.substr(pos, 1) === ";") { - var result9 = ";"; - pos += 1; - } else { - var result9 = null; - if (reportMatchFailures) { - matchFailed("\";\""); - } - } - if (result9 !== null) { - var result2 = [result4, result5, result6, result7, result8, result9]; - } else { - var result2 = null; - pos = savedPos1; - } - } else { - var result2 = null; - pos = savedPos1; - } - } else { - var result2 = null; - pos = savedPos1; - } + if (s6 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c13(s1, s5); + s0 = s1; } else { - var result2 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result2 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result2 = null; - pos = savedPos1; - } - var result3 = result2 !== null - ? (function(id, commentedVal) { - var result = Object.create(null); - result[id] = commentedVal.value; - result[id + "_comment"] = commentedVal.comment; - return result; - })(result2[0], result2[4]) - : null; - if (result3 !== null) { - var result1 = result3; - } else { - var result1 = null; - pos = savedPos0; - } - if (result1 !== null) { - var result0 = result1; - } else { - var result0 = null;; - }; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; - } - - function parse_CommentedIdentifier() { - var cacheKey = 'CommentedIdentifier@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - var result3 = parse_Identifier(); - if (result3 !== null) { - var result4 = parse__(); - if (result4 !== null) { - var result5 = parse_InlineComment(); - if (result5 !== null) { - var result1 = [result3, result4, result5]; - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } - var result2 = result1 !== null - ? (function(id, comment) { - var result = Object.create(null); - result.id = id; - result[id + "_comment"] = comment.trim(); - return result - })(result1[0], result1[2]) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; - } - - function parse_CommentedValue() { - var cacheKey = 'CommentedValue@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - var result3 = parse_Value(); - if (result3 !== null) { - var result4 = parse__(); - if (result4 !== null) { - var result5 = parse_InlineComment(); - if (result5 !== null) { - var result1 = [result3, result4, result5]; - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - var result2 = result1 !== null - ? (function(literal, comment) { - var result = Object.create(null) - result.comment = comment.trim(); - result.value = literal.trim(); - return result; - })(result1[0], result1[2]) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_InlineComment() { - var cacheKey = 'InlineComment@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - var result3 = parse_InlineCommentOpen(); - if (result3 !== null) { - if (input.substr(pos).match(/^[^*]/) !== null) { - var result6 = input.charAt(pos); - pos++; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseIdentifier(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 61) { + s3 = peg$c8; + peg$currPos++; } else { - var result6 = null; - if (reportMatchFailures) { - matchFailed("[^*]"); - } + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c9); } } - if (result6 !== null) { - var result4 = []; - while (result6 !== null) { - result4.push(result6); - if (input.substr(pos).match(/^[^*]/) !== null) { - var result6 = input.charAt(pos); - pos++; - } else { - var result6 = null; - if (reportMatchFailures) { - matchFailed("[^*]"); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseCommentedValue(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 59) { + s6 = peg$c10; + peg$currPos++; + } else { + s6 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c11); } } - } - } - } else { - var result4 = null; - } - if (result4 !== null) { - var result5 = parse_InlineCommentClose(); - if (result5 !== null) { - var result1 = [result3, result4, result5]; - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - var result2 = result1 !== null - ? (function(body) { return body.join('') })(result1[1]) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; - } - - function parse_InlineCommentOpen() { - var cacheKey = 'InlineCommentOpen@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - if (input.substr(pos, 2) === "/*") { - var result0 = "/*"; - pos += 2; - } else { - var result0 = null; - if (reportMatchFailures) { - matchFailed("\"/*\""); - } - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; - } - - function parse_InlineCommentClose() { - var cacheKey = 'InlineCommentClose@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - if (input.substr(pos, 2) === "*/") { - var result0 = "*/"; - pos += 2; - } else { - var result0 = null; - if (reportMatchFailures) { - matchFailed("\"*/\""); - } - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; - } - - function parse_DelimitedSection() { - var cacheKey = 'DelimitedSection@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - var result3 = parse_DelimitedSectionBegin(); - if (result3 !== null) { - var result4 = parse__(); - if (result4 !== null) { - var result9 = parse_AssignmentList(); - if (result9 !== null) { - var result5 = result9; - } else { - var result8 = parse_EmptyBody(); - if (result8 !== null) { - var result5 = result8; - } else { - var result5 = null;; - }; - } - if (result5 !== null) { - var result6 = parse__(); - if (result6 !== null) { - var result7 = parse_DelimitedSectionEnd(); - if (result7 !== null) { - var result1 = [result3, result4, result5, result6, result7]; + if (s6 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c14(s1, s5); + s0 = s1; } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } - var result2 = result1 !== null - ? (function(begin, fields) { - var section = Object.create(null); - section[begin.name] = fields - - return section - })(result1[0], result1[2]) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_DelimitedSectionBegin() { - var cacheKey = 'DelimitedSectionBegin@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; + } + + return s0; + } + + function peg$parseCommentedIdentifier() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parseIdentifier(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseInlineComment(); + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c15(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - - var savedPos0 = pos; - var savedPos1 = pos; - if (input.substr(pos, 9) === "/* Begin ") { - var result3 = "/* Begin "; - pos += 9; - } else { - var result3 = null; - if (reportMatchFailures) { - matchFailed("\"/* Begin \""); - } - } - if (result3 !== null) { - var result4 = parse_Identifier(); - if (result4 !== null) { - if (input.substr(pos, 11) === " section */") { - var result5 = " section */"; - pos += 11; - } else { - var result5 = null; - if (reportMatchFailures) { - matchFailed("\" section */\""); - } - } - if (result5 !== null) { - var result6 = parse_NewLine(); - if (result6 !== null) { - var result1 = [result3, result4, result5, result6]; - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - var result2 = result1 !== null - ? (function(sectionName) { return { name: sectionName } })(result1[1]) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_DelimitedSectionEnd() { - var cacheKey = 'DelimitedSectionEnd@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - if (input.substr(pos, 7) === "/* End ") { - var result3 = "/* End "; - pos += 7; - } else { - var result3 = null; - if (reportMatchFailures) { - matchFailed("\"/* End \""); - } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseCommentedValue() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parseValue(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseInlineComment(); + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c16(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - if (result3 !== null) { - var result4 = parse_Identifier(); - if (result4 !== null) { - if (input.substr(pos, 11) === " section */") { - var result5 = " section */"; - pos += 11; - } else { - var result5 = null; - if (reportMatchFailures) { - matchFailed("\" section */\""); - } - } - if (result5 !== null) { - var result6 = parse_NewLine(); - if (result6 !== null) { - var result1 = [result3, result4, result5, result6]; - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - var result2 = result1 !== null - ? (function(sectionName) { return { name: sectionName } })(result1[1]) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_Array() { - var cacheKey = 'Array@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - if (input.substr(pos, 1) === "(") { - var result3 = "("; - pos += 1; - } else { - var result3 = null; - if (reportMatchFailures) { - matchFailed("\"(\""); - } - } - if (result3 !== null) { - var result7 = parse_ArrayBody(); - if (result7 !== null) { - var result4 = result7; - } else { - var result6 = parse_EmptyArray(); - if (result6 !== null) { - var result4 = result6; - } else { - var result4 = null;; - }; - } - if (result4 !== null) { - if (input.substr(pos, 1) === ")") { - var result5 = ")"; - pos += 1; - } else { - var result5 = null; - if (reportMatchFailures) { - matchFailed("\")\""); - } - } - if (result5 !== null) { - var result1 = [result3, result4, result5]; - } else { - var result1 = null; - pos = savedPos1; - } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseInlineComment() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parseInlineCommentOpen(); + if (s1 !== peg$FAILED) { + s2 = []; + if (peg$c17.test(input.charAt(peg$currPos))) { + s3 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + if (peg$c17.test(input.charAt(peg$currPos))) { + s3 = input.charAt(peg$currPos); + peg$currPos++; } else { - var result1 = null; - pos = savedPos1; + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c18); } } - } else { - var result1 = null; - pos = savedPos1; - } - var result2 = result1 !== null - ? (function(arr) { return arr })(result1[1]) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + s2 = peg$FAILED; } - - function parse_EmptyArray() { - var cacheKey = 'EmptyArray@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var result1 = parse__(); - var result2 = result1 !== null - ? (function() { return [] })() - : null; - if (result2 !== null) { - var result0 = result2; + if (s2 !== peg$FAILED) { + s3 = peg$parseInlineCommentClose(); + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c19(s2); + s0 = s1; } else { - var result0 = null; - pos = savedPos0; + peg$currPos = s0; + s0 = peg$FAILED; } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_ArrayBody() { - var cacheKey = 'ArrayBody@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - var result3 = parse__(); - if (result3 !== null) { - var result4 = parse_ArrayEntry(); - if (result4 !== null) { - var result5 = parse__(); - if (result5 !== null) { - var result8 = parse_ArrayBody(); - var result6 = result8 !== null ? result8 : ''; - if (result6 !== null) { - var result7 = parse__(); - if (result7 !== null) { - var result1 = [result3, result4, result5, result6, result7]; - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseInlineCommentOpen() { + var s0; + + if (input.substr(peg$currPos, 2) === peg$c20) { + s0 = peg$c20; + peg$currPos += 2; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c21); } + } + + return s0; + } + + function peg$parseInlineCommentClose() { + var s0; + + if (input.substr(peg$currPos, 2) === peg$c22) { + s0 = peg$c22; + peg$currPos += 2; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c23); } + } + + return s0; + } + + function peg$parseDelimitedSection() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parseDelimitedSectionBegin(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseAssignmentList(); + if (s3 === peg$FAILED) { + s3 = peg$parseEmptyBody(); + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseDelimitedSectionEnd(); + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c24(s1, s3); + s0 = s1; } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result1 = null; - pos = savedPos1; - } - var result2 = result1 !== null - ? (function(head, tail) { - if (tail) { - tail.unshift(head); - return tail; - } else { - return [head]; - } - })(result1[1], result1[3]) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; + peg$currPos = s0; + s0 = peg$FAILED; } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; - } - - function parse_ArrayEntry() { - var cacheKey = 'ArrayEntry@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var result2 = parse_SimpleArrayEntry(); - if (result2 !== null) { - var result0 = result2; - } else { - var result1 = parse_CommentedArrayEntry(); - if (result1 !== null) { - var result0 = result1; - } else { - var result0 = null;; - }; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_SimpleArrayEntry() { - var cacheKey = 'SimpleArrayEntry@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - var result3 = parse_Value(); - if (result3 !== null) { - if (input.substr(pos, 1) === ",") { - var result4 = ","; - pos += 1; - } else { - var result4 = null; - if (reportMatchFailures) { - matchFailed("\",\""); - } - } - if (result4 !== null) { - var result1 = [result3, result4]; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseDelimitedSectionBegin() { + var s0, s1, s2, s3, s4; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 9) === peg$c25) { + s1 = peg$c25; + peg$currPos += 9; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c26); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseIdentifier(); + if (s2 !== peg$FAILED) { + if (input.substr(peg$currPos, 11) === peg$c27) { + s3 = peg$c27; + peg$currPos += 11; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c28); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parseNewLine(); + if (s4 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c29(s2); + s0 = s1; } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result1 = null; - pos = savedPos1; - } - var result2 = result1 !== null - ? (function(val) { return val })(result1[0]) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; + peg$currPos = s0; + s0 = peg$FAILED; } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_CommentedArrayEntry() { - var cacheKey = 'CommentedArrayEntry@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - var result3 = parse_Value(); - if (result3 !== null) { - var result4 = parse__(); - if (result4 !== null) { - var result5 = parse_InlineComment(); - if (result5 !== null) { - if (input.substr(pos, 1) === ",") { - var result6 = ","; - pos += 1; - } else { - var result6 = null; - if (reportMatchFailures) { - matchFailed("\",\""); - } - } - if (result6 !== null) { - var result1 = [result3, result4, result5, result6]; - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseDelimitedSectionEnd() { + var s0, s1, s2, s3, s4; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 7) === peg$c30) { + s1 = peg$c30; + peg$currPos += 7; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c31); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseIdentifier(); + if (s2 !== peg$FAILED) { + if (input.substr(peg$currPos, 11) === peg$c27) { + s3 = peg$c27; + peg$currPos += 11; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c28); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parseNewLine(); + if (s4 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c29(s2); + s0 = s1; } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result1 = null; - pos = savedPos1; - } - var result2 = result1 !== null - ? (function(val, comment) { - var result = Object.create(null); - result.value = val.trim(); - result.comment = comment.trim(); - return result; - })(result1[0], result1[2]) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; + peg$currPos = s0; + s0 = peg$FAILED; } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_Identifier() { - var cacheKey = 'Identifier@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - if (input.substr(pos).match(/^[A-Za-z0-9_]/) !== null) { - var result5 = input.charAt(pos); - pos++; - } else { - var result5 = null; - if (reportMatchFailures) { - matchFailed("[A-Za-z0-9_]"); - } - } - if (result5 !== null) { - var result3 = []; - while (result5 !== null) { - result3.push(result5); - if (input.substr(pos).match(/^[A-Za-z0-9_]/) !== null) { - var result5 = input.charAt(pos); - pos++; - } else { - var result5 = null; - if (reportMatchFailures) { - matchFailed("[A-Za-z0-9_]"); - } - } - } - } else { - var result3 = null; - } - var result4 = result3 !== null - ? (function(id) { return id.join('') })(result3) - : null; - if (result4 !== null) { - var result2 = result4; - } else { - var result2 = null; - pos = savedPos0; - } - if (result2 !== null) { - var result0 = result2; - } else { - var result1 = parse_QuotedString(); - if (result1 !== null) { - var result0 = result1; - } else { - var result0 = null;; - }; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseArray() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c32; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c33); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseArrayBody(); + if (s2 === peg$FAILED) { + s2 = peg$parseEmptyArray(); } - - function parse_Value() { - var cacheKey = 'Value@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var result4 = parse_Object(); - if (result4 !== null) { - var result0 = result4; + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s3 = peg$c34; + peg$currPos++; } else { - var result3 = parse_Array(); - if (result3 !== null) { - var result0 = result3; - } else { - var result2 = parse_NumberValue(); - if (result2 !== null) { - var result0 = result2; - } else { - var result1 = parse_StringValue(); - if (result1 !== null) { - var result0 = result1; - } else { - var result0 = null;; - }; - }; - }; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; - } - - function parse_NumberValue() { - var cacheKey = 'NumberValue@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c35); } } - - - var result2 = parse_DecimalValue(); - if (result2 !== null) { - var result0 = result2; + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c36(s2); + s0 = s1; } else { - var result1 = parse_IntegerValue(); - if (result1 !== null) { - var result0 = result1; - } else { - var result0 = null;; - }; + peg$currPos = s0; + s0 = peg$FAILED; } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_DecimalValue() { - var cacheKey = 'DecimalValue@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - var result3 = parse_IntegerValue(); - if (result3 !== null) { - if (input.substr(pos, 1) === ".") { - var result4 = "."; - pos += 1; - } else { - var result4 = null; - if (reportMatchFailures) { - matchFailed("\".\""); - } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseEmptyArray() { + var s0, s1; + + s0 = peg$currPos; + s1 = peg$parse_(); + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c37(); + } + s0 = s1; + + return s0; + } + + function peg$parseArrayBody() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parse_(); + if (s1 !== peg$FAILED) { + s2 = peg$parseArrayEntry(); + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + s4 = peg$parseArrayBody(); + if (s4 === peg$FAILED) { + s4 = null; } - if (result4 !== null) { - var result5 = parse_IntegerValue(); - if (result5 !== null) { - var result1 = [result3, result4, result5]; + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c38(s2, s4); + s0 = s1; } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result1 = null; - pos = savedPos1; - } - var result2 = result1 !== null - ? (function(decimal) { - // store decimals as strings - // as JS doesn't differentiate bw strings and numbers - return decimal.join('') - })(result1) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; + peg$currPos = s0; + s0 = peg$FAILED; } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_IntegerValue() { - var cacheKey = 'IntegerValue@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - var savedPos3 = pos; - var savedReportMatchFailuresVar1 = reportMatchFailures; - reportMatchFailures = false; - var result8 = parse_Alpha(); - reportMatchFailures = savedReportMatchFailuresVar1; - if (result8 === null) { - var result3 = ''; - } else { - var result3 = null; - pos = savedPos3; - } - if (result3 !== null) { - var result7 = parse_Digit(); - if (result7 !== null) { - var result4 = []; - while (result7 !== null) { - result4.push(result7); - var result7 = parse_Digit(); - } - } else { - var result4 = null; - } - if (result4 !== null) { - var savedPos2 = pos; - var savedReportMatchFailuresVar0 = reportMatchFailures; - reportMatchFailures = false; - var result6 = parse_Alpha(); - reportMatchFailures = savedReportMatchFailuresVar0; - if (result6 === null) { - var result5 = ''; - } else { - var result5 = null; - pos = savedPos2; - } - if (result5 !== null) { - var result1 = [result3, result4, result5]; - } else { - var result1 = null; - pos = savedPos1; - } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseArrayEntry() { + var s0; + + s0 = peg$parseSimpleArrayEntry(); + if (s0 === peg$FAILED) { + s0 = peg$parseCommentedArrayEntry(); + } + + return s0; + } + + function peg$parseSimpleArrayEntry() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = peg$parseValue(); + if (s1 !== peg$FAILED) { + s2 = peg$parseEndArrayEntry(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c39(s1); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseCommentedArrayEntry() { + var s0, s1, s2, s3, s4; + + s0 = peg$currPos; + s1 = peg$parseValue(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseInlineComment(); + if (s3 !== peg$FAILED) { + s4 = peg$parseEndArrayEntry(); + if (s4 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c40(s1, s3); + s0 = s1; } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s0; + s0 = peg$FAILED; } - var result2 = result1 !== null - ? (function(number) { return parseInt(number.join(''), 10) })(result1[1]) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_StringValue() { - var cacheKey = 'StringValue@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseEndArrayEntry() { + var s0, s1, s2, s3; + + if (input.charCodeAt(peg$currPos) === 44) { + s0 = peg$c41; + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c42); } + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parse_(); + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + if (input.charCodeAt(peg$currPos) === 41) { + s3 = peg$c34; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c35); } + } + peg$silentFails--; + if (s3 !== peg$FAILED) { + peg$currPos = s2; + s2 = void 0; + } else { + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - - var result2 = parse_QuotedString(); - if (result2 !== null) { - var result0 = result2; - } else { - var result1 = parse_LiteralString(); - if (result1 !== null) { - var result0 = result1; - } else { - var result0 = null;; - }; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_QuotedString() { - var cacheKey = 'QuotedString@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - var result3 = parse_DoubleQuote(); - if (result3 !== null) { - var result4 = parse_QuotedBody(); - if (result4 !== null) { - var result5 = parse_DoubleQuote(); - if (result5 !== null) { - var result1 = [result3, result4, result5]; - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; + } + + return s0; + } + + function peg$parseIdentifier() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = []; + if (peg$c43.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c44); } + } + if (s2 !== peg$FAILED) { + while (s2 !== peg$FAILED) { + s1.push(s2); + if (peg$c43.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c44); } } - var result2 = result1 !== null - ? (function(str) { return '"' + str + '"' })(result1[1]) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; } - - function parse_QuotedBody() { - var cacheKey = 'QuotedBody@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; + } else { + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c45(s1); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$parseQuotedString(); + } + + return s0; + } + + function peg$parseValue() { + var s0; + + s0 = peg$parseObject(); + if (s0 === peg$FAILED) { + s0 = peg$parseArray(); + if (s0 === peg$FAILED) { + s0 = peg$parseNumberValue(); + if (s0 === peg$FAILED) { + s0 = peg$parseStringValue(); } - - - var savedPos0 = pos; - var result3 = parse_NonQuote(); - if (result3 !== null) { - var result1 = []; - while (result3 !== null) { - result1.push(result3); - var result3 = parse_NonQuote(); - } - } else { - var result1 = null; - } - var result2 = result1 !== null - ? (function(str) { return str.join('') })(result1) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; } - - function parse_NonQuote() { - var cacheKey = 'NonQuote@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var result7 = parse_EscapedQuote(); - if (result7 !== null) { - var result0 = result7; - } else { - var savedPos0 = pos; - var savedPos1 = pos; - var savedPos2 = pos; - var savedReportMatchFailuresVar0 = reportMatchFailures; - reportMatchFailures = false; - var result6 = parse_DoubleQuote(); - reportMatchFailures = savedReportMatchFailuresVar0; - if (result6 === null) { - var result4 = ''; - } else { - var result4 = null; - pos = savedPos2; - } - if (result4 !== null) { - if (input.length > pos) { - var result5 = input.charAt(pos); - pos++; - } else { - var result5 = null; - if (reportMatchFailures) { - matchFailed('any character'); - } - } - if (result5 !== null) { - var result2 = [result4, result5]; - } else { - var result2 = null; - pos = savedPos1; - } - } else { - var result2 = null; - pos = savedPos1; - } - var result3 = result2 !== null - ? (function(char) { return char })(result2[1]) - : null; - if (result3 !== null) { - var result1 = result3; - } else { - var result1 = null; - pos = savedPos0; - } - if (result1 !== null) { - var result0 = result1; - } else { - var result0 = null;; - }; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } + + return s0; + } + + function peg$parseNumberValue() { + var s0; + + s0 = peg$parseDecimalValue(); + if (s0 === peg$FAILED) { + s0 = peg$parseIntegerValue(); + } + + return s0; + } + + function peg$parseDecimalValue() { + var s0, s1, s2, s3, s4; + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$parseIntegerValue(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s3 = peg$c46; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c47); } } - - function parse_EscapedQuote() { - var cacheKey = 'EscapedQuote@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - if (input.substr(pos, 1) === "\\") { - var result3 = "\\"; - pos += 1; - } else { - var result3 = null; - if (reportMatchFailures) { - matchFailed("\"\\\\\""); - } - } - if (result3 !== null) { - var result4 = parse_DoubleQuote(); - if (result4 !== null) { - var result1 = [result3, result4]; - } else { - var result1 = null; - pos = savedPos1; - } + if (s3 !== peg$FAILED) { + s4 = peg$parseIntegerValue(); + if (s4 !== peg$FAILED) { + s2 = [s2, s3, s4]; + s1 = s2; } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s1; + s1 = peg$FAILED; } - var result2 = result1 !== null - ? (function() { return '\\"' })() - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s1; + s1 = peg$FAILED; } - - function parse_LiteralString() { - var cacheKey = 'LiteralString@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var result3 = parse_LiteralChar(); - if (result3 !== null) { - var result1 = []; - while (result3 !== null) { - result1.push(result3); - var result3 = parse_LiteralChar(); - } - } else { - var result1 = null; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c48(s1); + } + s0 = s1; + + return s0; + } + + function peg$parseIntegerValue() { + var s0, s1, s2, s3, s4; + + s0 = peg$currPos; + s1 = peg$currPos; + peg$silentFails++; + s2 = peg$parseAlpha(); + peg$silentFails--; + if (s2 === peg$FAILED) { + s1 = void 0; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$parseDigit(); + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$parseDigit(); } - var result2 = result1 !== null - ? (function(literal) { return literal.join('') })(result1) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + s2 = peg$FAILED; } - - function parse_LiteralChar() { - var cacheKey = 'LiteralChar@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - var savedPos3 = pos; - var savedReportMatchFailuresVar1 = reportMatchFailures; - reportMatchFailures = false; - var result7 = parse_InlineCommentOpen(); - reportMatchFailures = savedReportMatchFailuresVar1; - if (result7 === null) { - var result3 = ''; - } else { - var result3 = null; - pos = savedPos3; - } - if (result3 !== null) { - var savedPos2 = pos; - var savedReportMatchFailuresVar0 = reportMatchFailures; - reportMatchFailures = false; - var result6 = parse_LineTerminator(); - reportMatchFailures = savedReportMatchFailuresVar0; - if (result6 === null) { - var result4 = ''; - } else { - var result4 = null; - pos = savedPos2; - } - if (result4 !== null) { - if (input.substr(pos).match(/^[^;,\n]/) !== null) { - var result5 = input.charAt(pos); - pos++; - } else { - var result5 = null; - if (reportMatchFailures) { - matchFailed("[^;,\\n]"); - } - } - if (result5 !== null) { - var result1 = [result3, result4, result5]; - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } + if (s2 !== peg$FAILED) { + s3 = peg$currPos; + peg$silentFails++; + s4 = peg$parseNonTerminator(); + peg$silentFails--; + if (s4 === peg$FAILED) { + s3 = void 0; } else { - var result1 = null; - pos = savedPos1; + peg$currPos = s3; + s3 = peg$FAILED; } - var result2 = result1 !== null - ? (function(char) { return char })(result1[2]) - : null; - if (result2 !== null) { - var result0 = result2; + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c49(s2); + s0 = s1; } else { - var result0 = null; - pos = savedPos0; + peg$currPos = s0; + s0 = peg$FAILED; } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_SingleLineComment() { - var cacheKey = 'SingleLineComment@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - if (input.substr(pos, 2) === "//") { - var result3 = "//"; - pos += 2; - } else { - var result3 = null; - if (reportMatchFailures) { - matchFailed("\"//\""); - } - } - if (result3 !== null) { - var result4 = parse__(); - if (result4 !== null) { - var result5 = parse_OneLineString(); - if (result5 !== null) { - var result6 = parse_NewLine(); - if (result6 !== null) { - var result1 = [result3, result4, result5, result6]; - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - var result2 = result1 !== null - ? (function(contents) { return contents })(result1[2]) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseStringValue() { + var s0; + + s0 = peg$parseQuotedString(); + if (s0 === peg$FAILED) { + s0 = peg$parseLiteralString(); + } + + return s0; + } + + function peg$parseQuotedString() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parseDoubleQuote(); + if (s1 !== peg$FAILED) { + s2 = peg$parseQuotedBody(); + if (s2 !== peg$FAILED) { + s3 = peg$parseDoubleQuote(); + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c50(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_OneLineString() { - var cacheKey = 'OneLineString@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var result1 = []; - var result3 = parse_NonLine(); - while (result3 !== null) { - result1.push(result3); - var result3 = parse_NonLine(); - } - var result2 = result1 !== null - ? (function(contents) { return contents.join('') })(result1) - : null; - if (result2 !== null) { - var result0 = result2; - } else { - var result0 = null; - pos = savedPos0; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseQuotedBody() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = []; + s2 = peg$parseNonQuote(); + if (s2 !== peg$FAILED) { + while (s2 !== peg$FAILED) { + s1.push(s2); + s2 = peg$parseNonQuote(); } - - function parse_Digit() { - var cacheKey = 'Digit@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - if (input.substr(pos).match(/^[0-9]/) !== null) { - var result0 = input.charAt(pos); - pos++; - } else { - var result0 = null; - if (reportMatchFailures) { - matchFailed("[0-9]"); - } - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c51(s1); + } + s0 = s1; + + return s0; + } + + function peg$parseNonQuote() { + var s0, s1, s2; + + s0 = peg$parseEscapedQuote(); + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$currPos; + peg$silentFails++; + s2 = peg$parseDoubleQuote(); + peg$silentFails--; + if (s2 === peg$FAILED) { + s1 = void 0; + } else { + peg$currPos = s1; + s1 = peg$FAILED; } - - function parse_Alpha() { - var cacheKey = 'Alpha@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - if (input.substr(pos).match(/^[A-Za-z]/) !== null) { - var result0 = input.charAt(pos); - pos++; + if (s1 !== peg$FAILED) { + if (input.length > peg$currPos) { + s2 = input.charAt(peg$currPos); + peg$currPos++; } else { - var result0 = null; - if (reportMatchFailures) { - matchFailed("[A-Za-z]"); - } - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; - } - - function parse_DoubleQuote() { - var cacheKey = 'DoubleQuote@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c52); } } - - - if (input.substr(pos, 1) === "\"") { - var result0 = "\""; - pos += 1; + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c53(s2); + s0 = s1; } else { - var result0 = null; - if (reportMatchFailures) { - matchFailed("\"\\\"\""); - } + peg$currPos = s0; + s0 = peg$FAILED; } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse__() { - var cacheKey = '_@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - var savedReportMatchFailures = reportMatchFailures; - reportMatchFailures = false; - var result0 = []; - var result1 = parse_whitespace(); - while (result1 !== null) { - result0.push(result1); - var result1 = parse_whitespace(); - } - reportMatchFailures = savedReportMatchFailures; - if (reportMatchFailures && result0 === null) { - matchFailed("whitespace"); - } - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } + + return s0; + } + + function peg$parseEscapedQuote() { + var s0, s1, s2; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s1 = peg$c54; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c55); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseDoubleQuote(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c56(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_whitespace() { - var cacheKey = 'whitespace@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var result2 = parse_NewLine(); - if (result2 !== null) { - var result0 = result2; - } else { - if (input.substr(pos).match(/^[ ]/) !== null) { - var result1 = input.charAt(pos); - pos++; - } else { - var result1 = null; - if (reportMatchFailures) { - matchFailed("[ ]"); - } - } - if (result1 !== null) { - var result0 = result1; - } else { - var result0 = null;; - }; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseLiteralString() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = []; + s2 = peg$parseLiteralChar(); + if (s2 !== peg$FAILED) { + while (s2 !== peg$FAILED) { + s1.push(s2); + s2 = peg$parseLiteralChar(); } - - function parse_NonLine() { - var cacheKey = 'NonLine@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var savedPos0 = pos; - var savedPos1 = pos; - var savedPos2 = pos; - var savedReportMatchFailuresVar0 = reportMatchFailures; - reportMatchFailures = false; - var result5 = parse_NewLine(); - reportMatchFailures = savedReportMatchFailuresVar0; - if (result5 === null) { - var result3 = ''; - } else { - var result3 = null; - pos = savedPos2; - } - if (result3 !== null) { - var result4 = parse_Char(); - if (result4 !== null) { - var result1 = [result3, result4]; - } else { - var result1 = null; - pos = savedPos1; - } - } else { - var result1 = null; - pos = savedPos1; - } - var result2 = result1 !== null - ? (function(char) { return char })(result1[1]) - : null; - if (result2 !== null) { - var result0 = result2; + } else { + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c57(s1); + } + s0 = s1; + + return s0; + } + + function peg$parseLiteralChar() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$currPos; + peg$silentFails++; + s2 = peg$parseInlineCommentOpen(); + peg$silentFails--; + if (s2 === peg$FAILED) { + s1 = void 0; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseLineTerminator(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s3 = peg$parseNonTerminator(); + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c53(s3); + s0 = s1; } else { - var result0 = null; - pos = savedPos0; + peg$currPos = s0; + s0 = peg$FAILED; } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_LineTerminator() { - var cacheKey = 'LineTerminator@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - var result2 = parse_NewLine(); - if (result2 !== null) { - var result0 = result2; - } else { - if (input.substr(pos, 1) === ";") { - var result1 = ";"; - pos += 1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseNonTerminator() { + var s0; + + if (peg$c58.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c59); } + } + + return s0; + } + + function peg$parseSingleLineComment() { + var s0, s1, s2, s3, s4; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 2) === peg$c60) { + s1 = peg$c60; + peg$currPos += 2; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c61); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseOneLineString(); + if (s3 !== peg$FAILED) { + s4 = peg$parseNewLine(); + if (s4 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c62(s3); + s0 = s1; } else { - var result1 = null; - if (reportMatchFailures) { - matchFailed("\";\""); - } + peg$currPos = s0; + s0 = peg$FAILED; } - if (result1 !== null) { - var result0 = result1; - } else { - var result0 = null;; - }; - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; - } - - function parse_NewLine() { - var cacheKey = 'NewLine@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - if (input.substr(pos).match(/^[\n\r]/) !== null) { - var result0 = input.charAt(pos); - pos++; } else { - var result0 = null; - if (reportMatchFailures) { - matchFailed("[\\n\\r]"); - } + peg$currPos = s0; + s0 = peg$FAILED; } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function parse_Char() { - var cacheKey = 'Char@' + pos; - var cachedResult = cache[cacheKey]; - if (cachedResult) { - pos = cachedResult.nextPos; - return cachedResult.result; - } - - - if (input.length > pos) { - var result0 = input.charAt(pos); - pos++; - } else { - var result0 = null; - if (reportMatchFailures) { - matchFailed('any character'); - } - } - - - - cache[cacheKey] = { - nextPos: pos, - result: result0 - }; - return result0; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseOneLineString() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = []; + s2 = peg$parseNonLine(); + while (s2 !== peg$FAILED) { + s1.push(s2); + s2 = peg$parseNonLine(); + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c63(s1); + } + s0 = s1; + + return s0; + } + + function peg$parseDigit() { + var s0; + + if (peg$c64.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c65); } + } + + return s0; + } + + function peg$parseAlpha() { + var s0; + + if (peg$c66.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c67); } + } + + return s0; + } + + function peg$parseDoubleQuote() { + var s0; + + if (input.charCodeAt(peg$currPos) === 34) { + s0 = peg$c68; + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c69); } + } + + return s0; + } + + function peg$parse_() { + var s0, s1; + + peg$silentFails++; + s0 = []; + s1 = peg$parsewhitespace(); + while (s1 !== peg$FAILED) { + s0.push(s1); + s1 = peg$parsewhitespace(); + } + peg$silentFails--; + if (s0 === peg$FAILED) { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c70); } + } + + return s0; + } + + function peg$parsewhitespace() { + var s0; + + s0 = peg$parseNewLine(); + if (s0 === peg$FAILED) { + if (peg$c71.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c72); } } - - function buildErrorMessage() { - function buildExpected(failuresExpected) { - failuresExpected.sort(); - - var lastFailure = null; - var failuresExpectedUnique = []; - for (var i = 0; i < failuresExpected.length; i++) { - if (failuresExpected[i] !== lastFailure) { - failuresExpectedUnique.push(failuresExpected[i]); - lastFailure = failuresExpected[i]; - } - } - - switch (failuresExpectedUnique.length) { - case 0: - return 'end of input'; - case 1: - return failuresExpectedUnique[0]; - default: - return failuresExpectedUnique.slice(0, failuresExpectedUnique.length - 1).join(', ') - + ' or ' - + failuresExpectedUnique[failuresExpectedUnique.length - 1]; - } - } - - var expected = buildExpected(rightmostMatchFailuresExpected); - var actualPos = Math.max(pos, rightmostMatchFailuresPos); - var actual = actualPos < input.length - ? quote(input.charAt(actualPos)) - : 'end of input'; - - return 'Expected ' + expected + ' but ' + actual + ' found.'; + } + + return s0; + } + + function peg$parseNonLine() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = peg$currPos; + peg$silentFails++; + s2 = peg$parseNewLine(); + peg$silentFails--; + if (s2 === peg$FAILED) { + s1 = void 0; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s2 = peg$parseChar(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c53(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; } - - function computeErrorPosition() { - /* - * The first idea was to use |String.split| to break the input up to the - * error position along newlines and derive the line and column from - * there. However IE's |split| implementation is so broken that it was - * enough to prevent it. - */ - - var line = 1; - var column = 1; - var seenCR = false; - - for (var i = 0; i < rightmostMatchFailuresPos; i++) { - var ch = input.charAt(i); - if (ch === '\n') { - if (!seenCR) { line++; } - column = 1; - seenCR = false; - } else if (ch === '\r' | ch === '\u2028' || ch === '\u2029') { - line++; - column = 1; - seenCR = true; - } else { - column++; - seenCR = false; - } - } - - return { line: line, column: column }; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseLineTerminator() { + var s0; + + s0 = peg$parseNewLine(); + if (s0 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 59) { + s0 = peg$c10; + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c11); } } - - - - function merge(hash, secondHash) { - - secondHash = secondHash[0] - - for(var i in secondHash) - - hash[i] = secondHash[i] - - - - return hash; - - } - - - - var result = parseFunctions[startRule](); - - /* - * The parser is now in one of the following three states: - * - * 1. The parser successfully parsed the whole input. - * - * - |result !== null| - * - |pos === input.length| - * - |rightmostMatchFailuresExpected| may or may not contain something - * - * 2. The parser successfully parsed only a part of the input. - * - * - |result !== null| - * - |pos < input.length| - * - |rightmostMatchFailuresExpected| may or may not contain something - * - * 3. The parser did not successfully parse any part of the input. - * - * - |result === null| - * - |pos === 0| - * - |rightmostMatchFailuresExpected| contains at least one failure - * - * All code following this comment (including called functions) must - * handle these states. - */ - if (result === null || pos !== input.length) { - var errorPosition = computeErrorPosition(); - throw new this.SyntaxError( - buildErrorMessage(), - errorPosition.line, - errorPosition.column - ); + } + + return s0; + } + + function peg$parseNewLine() { + var s0; + + if (peg$c73.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c74); } + } + + return s0; + } + + function peg$parseChar() { + var s0; + + if (input.length > peg$currPos) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c52); } + } + + return s0; + } + + + function merge_obj(obj, secondObj) { + if (!obj) + return secondObj; + + for(var i in secondObj) + obj[i] = merge_obj(obj[i], secondObj[i]); + + return obj; } - - return result; - }, - - /* Returns the parser source code. */ - toSource: function() { return this._source; } - }; - - /* Thrown when a parser encounters a syntax error. */ - - result.SyntaxError = function(message, line, column) { - this.name = 'SyntaxError'; - this.message = message; - this.line = line; - this.column = column; - }; - - result.SyntaxError.prototype = Error.prototype; - - return result; -})(); + + + peg$result = peg$startRuleFunction(); + + if (peg$result !== peg$FAILED && peg$currPos === input.length) { + return peg$result; + } else { + if (peg$result !== peg$FAILED && peg$currPos < input.length) { + peg$fail(peg$endExpectation()); + } + + throw peg$buildStructuredError( + peg$maxFailExpected, + peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, + peg$maxFailPos < input.length + ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) + : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) + ); + } +} + +module.exports = { + SyntaxError: peg$SyntaxError, + parse: peg$parse +}; diff --git a/lib/parser/pbxproj.pegjs b/lib/parser/pbxproj.pegjs index 4f9c884..c612689 100644 --- a/lib/parser/pbxproj.pegjs +++ b/lib/parser/pbxproj.pegjs @@ -1,10 +1,12 @@ { - function merge(hash, secondHash) { - secondHash = secondHash[0] - for(var i in secondHash) - hash[i] = secondHash[i] + function merge_obj(obj, secondObj) { + if (!obj) + return secondObj; - return hash; + for(var i in secondObj) + obj[i] = merge_obj(obj[i], secondObj[i]); + + return obj; } } @@ -36,15 +38,14 @@ EmptyBody { return Object.create(null) } AssignmentList - = _ head:Assignment _ tail:AssignmentList* _ - { - if (tail) return merge(head,tail) - else return head - } - / _ head:DelimitedSection _ tail:AssignmentList* + = _ list:((a:Assignment / d:DelimitedSection) _)+ { - if (tail) return merge(head,tail) - else return head + var returnObject = list[0][0]; + for(var i = 1; i < list.length; i++){ + var another = list[i][0]; + returnObject = merge_obj(returnObject, another); + } + return returnObject; } /* @@ -57,7 +58,7 @@ Assignment SimpleAssignment = id:Identifier _ "=" _ val:Value ";" - { + { var result = Object.create(null); result[id] = val return result @@ -155,10 +156,10 @@ ArrayEntry = SimpleArrayEntry / CommentedArrayEntry SimpleArrayEntry - = val:Value "," { return val } + = val:Value EndArrayEntry { return val } CommentedArrayEntry - = val:Value _ comment:InlineComment "," + = val:Value _ comment:InlineComment EndArrayEntry { var result = Object.create(null); result.value = val.trim(); @@ -166,11 +167,14 @@ CommentedArrayEntry return result; } +EndArrayEntry + = "," / _ &")" + /* * Identifiers and Values */ Identifier - = id:[A-Za-z0-9_]+ { return id.join('') } + = id:[A-Za-z0-9_.]+ { return id.join('') } / QuotedString Value @@ -181,14 +185,14 @@ NumberValue DecimalValue = decimal:(IntegerValue "." IntegerValue) - { + { // store decimals as strings // as JS doesn't differentiate bw strings and numbers return decimal.join('') } IntegerValue - = !Alpha number:Digit+ !Alpha + = !Alpha number:Digit+ !NonTerminator { return parseInt(number.join(''), 10) } StringValue @@ -210,9 +214,12 @@ LiteralString = literal:LiteralChar+ { return literal.join('') } LiteralChar - = !InlineCommentOpen !LineTerminator char:[^;,\n] + = !InlineCommentOpen !LineTerminator char:NonTerminator { return char } +NonTerminator + = [^;,\n] + /* * SingleLineComment - used for the encoding comment */ diff --git a/lib/pbxFile.js b/lib/pbxFile.js index 0f76b31..768122a 100644 --- a/lib/pbxFile.js +++ b/lib/pbxFile.js @@ -1,88 +1,215 @@ var path = require('path'), - M_EXTENSION = /[.]m$/, SOURCE_FILE = 'sourcecode.c.objc', - H_EXTENSION = /[.]h$/, HEADER_FILE = 'sourcecode.c.h', - BUNDLE_EXTENSION = /[.]bundle$/, BUNDLE = '"wrapper.plug-in"', - XIB_EXTENSION = /[.]xib$/, XIB_FILE = 'file.xib', - DYLIB_EXTENSION = /[.]dylib$/, DYLIB = '"compiled.mach-o.dylib"', - FRAMEWORK_EXTENSION = /[.]framework/, FRAMEWORK = 'wrapper.framework', - ARCHIVE_EXTENSION = /[.]a$/, ARCHIVE = 'archive.ar', - DEFAULT_SOURCE_TREE = '""', - DEFAULT_FILE_ENCODING = 4; - -function detectLastType(path) { - if (M_EXTENSION.test(path)) - return SOURCE_FILE; + util = require('util'); + +var DEFAULT_SOURCETREE = '""', + DEFAULT_PRODUCT_SOURCETREE = 'BUILT_PRODUCTS_DIR', + DEFAULT_FILEENCODING = 4, + DEFAULT_GROUP = 'Resources', + DEFAULT_FILETYPE = 'unknown'; + +var FILETYPE_BY_EXTENSION = { + a: 'archive.ar', + app: 'wrapper.application', + appex: 'wrapper.app-extension', + bundle: 'wrapper.plug-in', + dylib: 'compiled.mach-o.dylib', + framework: 'wrapper.framework', + h: 'sourcecode.c.h', + m: 'sourcecode.c.objc', + markdown: 'text', + mdimporter: 'wrapper.cfbundle', + octest: 'wrapper.cfbundle', + pch: 'sourcecode.c.h', + plist: 'text.plist.xml', + sh: 'text.script.sh', + swift: 'sourcecode.swift', + 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.objc': 'Sources', + 'sourcecode.swift': '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.c.objc': 4, + 'sourcecode.swift': 4, + 'text': 4, + 'text.plist.xml': 4, + 'text.script.sh': 4, + 'text.xcconfig': 4, + 'text.plist.strings': 4 + }; + + +function unquoted(text){ + return text.replace (/(^")|("$)/g, '') +} - if (H_EXTENSION.test(path)) - return HEADER_FILE; +function detectType(filePath) { + var extension = path.extname(filePath).substring(1), + filetype = FILETYPE_BY_EXTENSION[unquoted(extension)]; - if (BUNDLE_EXTENSION.test(path)) - return BUNDLE; + if (!filetype) { + return DEFAULT_FILETYPE; + } - if (XIB_EXTENSION.test(path)) - return XIB_FILE; + return filetype; +} - if (FRAMEWORK_EXTENSION.test(path)) - return FRAMEWORK; +function defaultExtension(fileRef) { + var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType; - if (DYLIB_EXTENSION.test(path)) - return DYLIB; + for(var extension in FILETYPE_BY_EXTENSION) { + if(FILETYPE_BY_EXTENSION.hasOwnProperty(unquoted(extension)) ) { + if(FILETYPE_BY_EXTENSION[unquoted(extension)] === filetype ) + return extension; + } + } +} - if (ARCHIVE_EXTENSION.test(path)) - return ARCHIVE; +function defaultEncoding(fileRef) { + var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType, + encoding = ENCODING_BY_FILETYPE[unquoted(filetype)]; - // dunno - return 'unknown'; + if (encoding) { + return encoding; + } } -function fileEncoding(file) { - if (file.lastType != BUNDLE) { - return DEFAULT_FILE_ENCODING; +function detectGroup(fileRef, opt) { + var extension = path.extname(fileRef.basename).substring(1), + filetype = fileRef.lastKnownFileType || fileRef.explicitFileType, + groupName = GROUP_BY_FILETYPE[unquoted(filetype)]; + + if (extension === 'xcdatamodeld') { + return 'Sources'; } + + if (opt.customFramework && opt.embed) { + return GROUP_BY_FILETYPE['embedded.framework']; + } + + if (!groupName) { + return DEFAULT_GROUP; + } + + return groupName; } -function defaultSourceTree(file) { - if (file.lastType == DYLIB || file.lastType == FRAMEWORK) { - return 'SDKROOT'; - } else { - return DEFAULT_SOURCE_TREE; +function detectSourcetree(fileRef) { + + var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType, + sourcetree = SOURCETREE_BY_FILETYPE[unquoted(filetype)]; + + if (fileRef.explicitFileType) { + return DEFAULT_PRODUCT_SOURCETREE; + } + + if (fileRef.customFramework) { + return DEFAULT_SOURCETREE; } + + if (!sourcetree) { + return DEFAULT_SOURCETREE; + } + + return sourcetree; } -function correctPath(file, filepath) { - if (file.lastType == FRAMEWORK) { - return 'System/Library/Frameworks/' + filepath; - } else if (file.lastType == DYLIB) { - return 'usr/lib/' + filepath; - } else { - return filepath; +function defaultPath(fileRef, filePath) { + var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType, + defaultPath = PATH_BY_FILETYPE[unquoted(filetype)]; + + if (fileRef.customFramework) { + return filePath; + } + + if (defaultPath) { + return path.join(defaultPath, path.basename(filePath)); } + + return filePath; } -function correctGroup(file) { - if (file.lastType == SOURCE_FILE) { - return 'Sources'; - } else if (file.lastType == DYLIB || file.lastType == ARCHIVE) { - return 'Frameworks'; - } else { - return 'Resources'; +function defaultGroup(fileRef) { + var groupName = GROUP_BY_FILETYPE[fileRef.lastKnownFileType]; + + if (!groupName) { + return DEFAULT_GROUP; } + + return defaultGroup; } function pbxFile(filepath, opt) { var opt = opt || {}; - this.lastType = opt.lastType || detectLastType(filepath); - - this.path = correctPath(this, filepath); this.basename = path.basename(filepath); - this.group = correctGroup(this); + this.lastKnownFileType = opt.lastKnownFileType || detectType(filepath); + this.group = detectGroup(this, opt); + + // for custom frameworks + if (opt.customFramework == true) { + this.customFramework = true; + this.dirname = path.dirname(filepath).replace(/\\/g, '/'); + } + + this.path = defaultPath(this, filepath).replace(/\\/g, '/'); + this.fileEncoding = this.defaultEncoding = opt.defaultEncoding || defaultEncoding(this); + + // When referencing products / build output files + if (opt.explicitFileType) { + this.explicitFileType = opt.explicitFileType; + this.basename = this.basename + '.' + defaultExtension(this); + delete this.path; + delete this.lastKnownFileType; + delete this.group; + delete this.defaultEncoding; + } - this.sourceTree = opt.sourceTree || defaultSourceTree(this); - this.fileEncoding = opt.fileEncoding || fileEncoding(this); + this.sourceTree = opt.sourceTree || detectSourcetree(this); + this.includeInIndex = 0; - if (opt.weak && opt.weak === true) - this.settings = { ATTRIBUTES: ['Weak'] }; + if (opt.weak && opt.weak === true) + this.settings = { ATTRIBUTES: ['Weak'] }; + + if (opt.compilerFlags) { + if (!this.settings) + this.settings = {}; + this.settings.COMPILER_FLAGS = util.format('"%s"', opt.compilerFlags); + } + + if (opt.embed && opt.sign) { + if (!this.settings) + this.settings = {}; + if (!this.settings.ATTRIBUTES) + this.settings.ATTRIBUTES = []; + this.settings.ATTRIBUTES.push('CodeSignOnCopy'); + } } module.exports = pbxFile; diff --git a/lib/pbxProject.js b/lib/pbxProject.js index 2abfba8..18033bb 100644 --- a/lib/pbxProject.js +++ b/lib/pbxProject.js @@ -2,12 +2,13 @@ var util = require('util'), f = util.format, EventEmitter = require('events').EventEmitter, path = require('path'), - uuid = require('node-uuid'), + uuid = require('uuid'), fork = require('child_process').fork, pbxWriter = require('./pbxWriter'), pbxFile = require('./pbxFile'), fs = require('fs'), parser = require('./parser/pbxproj'), + plist = require('simple-plist'), COMMENT_KEY = /_comment$/ function pbxProject(filename) { @@ -19,10 +20,10 @@ function pbxProject(filename) { util.inherits(pbxProject, EventEmitter) -pbxProject.prototype.parse = function (cb) { +pbxProject.prototype.parse = function(cb) { var worker = fork(__dirname + '/parseJob.js', [this.filepath]) - worker.on('message', function (msg) { + worker.on('message', function(msg) { if (msg.name == 'SyntaxError' || msg.code) { this.emit('error', msg); } else { @@ -39,19 +40,19 @@ pbxProject.prototype.parse = function (cb) { return this; } -pbxProject.prototype.parseSync = function () { +pbxProject.prototype.parseSync = function() { var file_contents = fs.readFileSync(this.filepath, 'utf-8'); this.hash = parser.parse(file_contents); return this; } -pbxProject.prototype.writeSync = function () { +pbxProject.prototype.writeSync = function() { this.writer = new pbxWriter(this.hash); return this.writer.writeSync(); } -pbxProject.prototype.allUuids = function () { +pbxProject.prototype.allUuids = function() { var sections = this.hash.project.objects, uuids = [], section; @@ -61,18 +62,18 @@ pbxProject.prototype.allUuids = function () { uuids = uuids.concat(Object.keys(section)) } - uuids = uuids.filter(function (str) { + uuids = uuids.filter(function(str) { return !COMMENT_KEY.test(str) && str.length == 24; }); return uuids; } -pbxProject.prototype.generateUuid = function () { +pbxProject.prototype.generateUuid = function() { var id = uuid.v4() - .replace(/-/g,'') - .substr(0,24) - .toUpperCase() + .replace(/-/g, '') + .substr(0, 24) + .toUpperCase() if (this.allUuids().indexOf(id) >= 0) { return this.generateUuid(); @@ -81,7 +82,7 @@ pbxProject.prototype.generateUuid = function () { } } -pbxProject.prototype.addPluginFile = function (path, opt) { +pbxProject.prototype.addPluginFile = function(path, opt) { var file = new pbxFile(path, opt); file.plugin = true; // durr @@ -98,7 +99,7 @@ pbxProject.prototype.addPluginFile = function (path, opt) { return file; } -pbxProject.prototype.removePluginFile = function (path, opt) { +pbxProject.prototype.removePluginFile = function(path, opt) { var file = new pbxFile(path, opt); correctForPluginsPath(file, this); @@ -108,11 +109,49 @@ pbxProject.prototype.removePluginFile = function (path, opt) { return file; } -pbxProject.prototype.addSourceFile = function (path, opt) { - var file = this.addPluginFile(path, opt); +pbxProject.prototype.addProductFile = function(targetPath, opt) { + var file = new pbxFile(targetPath, opt); + + file.includeInIndex = 0; + file.fileRef = this.generateUuid(); + file.target = opt ? opt.target : undefined; + file.group = opt ? opt.group : undefined; + file.uuid = this.generateUuid(); + file.path = file.basename; + + this.addToPbxFileReferenceSection(file); + this.addToProductsPbxGroup(file); // PBXGroup + + return file; +} + +pbxProject.prototype.removeProductFile = function(path, opt) { + var file = new pbxFile(path, opt); + + this.removeFromProductsPbxGroup(file); // PBXGroup + + return file; +} + +/** + * + * @param path {String} + * @param opt {Object} see pbxFile for avail options + * @param group {String} group key + * @returns {Object} file; see pbxFile + */ +pbxProject.prototype.addSourceFile = function (path, opt, group) { + var file; + if (group) { + file = this.addFile(path, group, opt); + } + else { + file = this.addPluginFile(path, opt); + } if (!file) return false; + file.target = opt ? opt.target : undefined; file.uuid = this.generateUuid(); this.addToPbxBuildFileSection(file); // PBXBuildFile @@ -121,23 +160,68 @@ pbxProject.prototype.addSourceFile = function (path, opt) { return file; } -pbxProject.prototype.removeSourceFile = function (path, opt) { - var file = this.removePluginFile(path, opt) +/** + * + * @param path {String} + * @param opt {Object} see pbxFile for avail options + * @param group {String} group key + * @returns {Object} file; see pbxFile + */ +pbxProject.prototype.removeSourceFile = function (path, opt, group) { + var file; + if (group) { + file = this.removeFile(path, group, opt); + } + else { + file = this.removePluginFile(path, opt); + } + file.target = opt ? opt.target : undefined; this.removeFromPbxBuildFileSection(file); // PBXBuildFile this.removeFromPbxSourcesBuildPhase(file); // PBXSourcesBuildPhase return file; } -pbxProject.prototype.addHeaderFile = function (path, opt) { - return this.addPluginFile(path, opt) +/** + * + * @param path {String} + * @param opt {Object} see pbxFile for avail options + * @param group {String} group key + * @returns {Object} file; see pbxFile + */ +pbxProject.prototype.addHeaderFile = function (path, opt, group) { + if (group) { + return this.addFile(path, group, opt); + } + else { + return this.addPluginFile(path, opt); + } } -pbxProject.prototype.removeHeaderFile = function (path, opt) { - return this.removePluginFile(path, opt) +/** + * + * @param path {String} + * @param opt {Object} see pbxFile for avail options + * @param group {String} group key + * @returns {Object} file; see pbxFile + */ +pbxProject.prototype.removeHeaderFile = function (path, opt, group) { + if (group) { + return this.removeFile(path, group, opt); + } + else { + return this.removePluginFile(path, opt); + } } -pbxProject.prototype.addResourceFile = function (path, opt) { +/** + * + * @param path {String} + * @param opt {Object} see pbxFile for avail options + * @param group {String} group key + * @returns {Object} file; see pbxFile + */ +pbxProject.prototype.addResourceFile = function(path, opt, group) { opt = opt || {}; var file; @@ -151,65 +235,196 @@ pbxProject.prototype.addResourceFile = function (path, opt) { } file.uuid = this.generateUuid(); + file.target = opt ? opt.target : undefined; if (!opt.plugin) { correctForResourcesPath(file, this); file.fileRef = this.generateUuid(); } - this.addToPbxBuildFileSection(file); // PBXBuildFile - this.addToPbxResourcesBuildPhase(file); // PBXResourcesBuildPhase + if (!opt.variantGroup) { + this.addToPbxBuildFileSection(file); // PBXBuildFile + this.addToPbxResourcesBuildPhase(file); // PBXResourcesBuildPhase + } if (!opt.plugin) { this.addToPbxFileReferenceSection(file); // PBXFileReference - this.addToResourcesPbxGroup(file); // PBXGroup + if (group) { + if (this.getPBXGroupByKey(group)) { + this.addToPbxGroup(file, group); //Group other than Resources (i.e. 'splash') + } + else if (this.getPBXVariantGroupByKey(group)) { + this.addToPbxVariantGroup(file, group); // PBXVariantGroup + } + } + else { + this.addToResourcesPbxGroup(file); // PBXGroup + } + } return file; } -pbxProject.prototype.removeResourceFile = function (path, opt) { +/** + * + * @param path {String} + * @param opt {Object} see pbxFile for avail options + * @param group {String} group key + * @returns {Object} file; see pbxFile + */ +pbxProject.prototype.removeResourceFile = function(path, opt, group) { var file = new pbxFile(path, opt); - + file.target = opt ? opt.target : undefined; + correctForResourcesPath(file, this); this.removeFromPbxBuildFileSection(file); // PBXBuildFile this.removeFromPbxFileReferenceSection(file); // PBXFileReference - this.removeFromResourcesPbxGroup(file); // PBXGroup + if (group) { + if (this.getPBXGroupByKey(group)) { + this.removeFromPbxGroup(file, group); //Group other than Resources (i.e. 'splash') + } + else if (this.getPBXVariantGroupByKey(group)) { + this.removeFromPbxVariantGroup(file, group); // PBXVariantGroup + } + } + else { + this.removeFromResourcesPbxGroup(file); // PBXGroup + } this.removeFromPbxResourcesBuildPhase(file); // PBXResourcesBuildPhase - + return file; } -pbxProject.prototype.addFramework = function (path, opt) { - var file = new pbxFile(path, opt); +pbxProject.prototype.addFramework = function(fpath, opt) { + var customFramework = opt && opt.customFramework == true; + var link = !opt || (opt.link == undefined || opt.link); //defaults to true if not specified + var embed = opt && opt.embed; //defaults to false if not specified - // catch duplicates - if (this.hasFile(file.path)) return false; + if (opt) { + delete opt.embed; + } + + var file = new pbxFile(fpath, opt); file.uuid = this.generateUuid(); file.fileRef = this.generateUuid(); + file.target = opt ? opt.target : undefined; + + if (this.hasFile(file.path)) return false; this.addToPbxBuildFileSection(file); // PBXBuildFile this.addToPbxFileReferenceSection(file); // PBXFileReference this.addToFrameworksPbxGroup(file); // PBXGroup - this.addToPbxFrameworksBuildPhase(file); // PBXFrameworksBuildPhase + + if (link) { + this.addToPbxFrameworksBuildPhase(file); // PBXFrameworksBuildPhase + } + + if (customFramework) { + this.addToFrameworkSearchPaths(file); + + if (embed) { + opt.embed = embed; + var embeddedFile = new pbxFile(fpath, opt); + + embeddedFile.uuid = this.generateUuid(); + embeddedFile.fileRef = file.fileRef; + + //keeping a separate PBXBuildFile entry for Embed Frameworks + this.addToPbxBuildFileSection(embeddedFile); // PBXBuildFile + + this.addToPbxEmbedFrameworksBuildPhase(embeddedFile); // PBXCopyFilesBuildPhase + + return embeddedFile; + } + } return file; } -pbxProject.prototype.removeFramework = function (path, opt) { - var file = new pbxFile(path, opt); +pbxProject.prototype.removeFramework = function(fpath, opt) { + var embed = opt && opt.embed; + + if (opt) { + delete opt.embed; + } + + var file = new pbxFile(fpath, opt); + file.target = opt ? opt.target : undefined; + + this.removeFromPbxBuildFileSection(file); // PBXBuildFile + this.removeFromPbxFileReferenceSection(file); // PBXFileReference + this.removeFromFrameworksPbxGroup(file); // PBXGroup + this.removeFromPbxFrameworksBuildPhase(file); // PBXFrameworksBuildPhase + + if (opt && opt.customFramework) { + this.removeFromFrameworkSearchPaths(file); + } + + opt = opt || {}; + opt.embed = true; + var embeddedFile = new pbxFile(fpath, opt); + + embeddedFile.fileRef = file.fileRef; + + this.removeFromPbxBuildFileSection(embeddedFile); // PBXBuildFile + this.removeFromPbxEmbedFrameworksBuildPhase(embeddedFile); // PBXCopyFilesBuildPhase + + return file; +} + + +pbxProject.prototype.addCopyfile = function(fpath, opt) { + var file = new pbxFile(fpath, opt); + + // catch duplicates + if (this.hasFile(file.path)) { + file = this.hasFile(file.path); + } + + file.fileRef = file.uuid = this.generateUuid(); + file.target = opt ? opt.target : undefined; + + this.addToPbxBuildFileSection(file); // PBXBuildFile + this.addToPbxFileReferenceSection(file); // PBXFileReference + this.addToPbxCopyfilesBuildPhase(file); // PBXCopyFilesBuildPhase + + return file; +} + +pbxProject.prototype.pbxCopyfilesBuildPhaseObj = function(target) { + return this.buildPhaseObject('PBXCopyFilesBuildPhase', 'Copy Files', target); +} + +pbxProject.prototype.addToPbxCopyfilesBuildPhase = function(file) { + var sources = this.buildPhaseObject('PBXCopyFilesBuildPhase', 'Copy Files', file.target); + sources.files.push(pbxBuildPhaseObj(file)); +} + +pbxProject.prototype.removeCopyfile = function(fpath, opt) { + var file = new pbxFile(fpath, opt); + file.target = opt ? opt.target : undefined; this.removeFromPbxBuildFileSection(file); // PBXBuildFile this.removeFromPbxFileReferenceSection(file); // PBXFileReference - this.removeFromFrameworksPbxGroup(file); // PBXGroup - this.removeFromPbxFrameworksBuildPhase(file); // PBXFrameworksBuildPhase + this.removeFromPbxCopyfilesBuildPhase(file); // PBXFrameworksBuildPhase return file; } -pbxProject.prototype.addStaticLibrary = function (path, opt) { +pbxProject.prototype.removeFromPbxCopyfilesBuildPhase = function(file) { + var sources = this.pbxCopyfilesBuildPhaseObj(file.target); + for (i in sources.files) { + if (sources.files[i].comment == longComment(file)) { + sources.files.splice(i, 1); + break; + } + } +} + +pbxProject.prototype.addStaticLibrary = function(path, opt) { opt = opt || {}; var file; @@ -223,6 +438,7 @@ pbxProject.prototype.addStaticLibrary = function (path, opt) { } file.uuid = this.generateUuid(); + file.target = opt ? opt.target : undefined; if (!opt.plugin) { file.fileRef = this.generateUuid(); @@ -231,24 +447,24 @@ pbxProject.prototype.addStaticLibrary = function (path, opt) { this.addToPbxBuildFileSection(file); // PBXBuildFile this.addToPbxFrameworksBuildPhase(file); // PBXFrameworksBuildPhase - this.ensureCorrectSearchPaths(file); // make sure it gets built! + this.addToLibrarySearchPaths(file); // make sure it gets built! return file; } // helper addition functions -pbxProject.prototype.addToPbxBuildFileSection = function (file) { +pbxProject.prototype.addToPbxBuildFileSection = function(file) { var commentKey = f("%s_comment", file.uuid); this.pbxBuildFileSection()[file.uuid] = pbxBuildFileObj(file); this.pbxBuildFileSection()[commentKey] = pbxBuildFileComment(file); } -pbxProject.prototype.removeFromPbxBuildFileSection = function (file) { +pbxProject.prototype.removeFromPbxBuildFileSection = function(file) { var uuid; - for(uuid in this.pbxBuildFileSection()) { - if(this.pbxBuildFileSection()[uuid].fileRef_comment == file.basename) { + for (uuid in this.pbxBuildFileSection()) { + if (this.pbxBuildFileSection()[uuid].fileRef_comment == file.basename) { file.uuid = uuid; delete this.pbxBuildFileSection()[uuid]; } @@ -257,142 +473,471 @@ pbxProject.prototype.removeFromPbxBuildFileSection = function (file) { delete this.pbxBuildFileSection()[commentKey]; } -pbxProject.prototype.addToPbxFileReferenceSection = function (file) { +pbxProject.prototype.addPbxGroup = function(filePathsArray, name, path, sourceTree) { + var groups = this.hash.project.objects['PBXGroup'], + pbxGroupUuid = this.generateUuid(), + commentKey = f("%s_comment", pbxGroupUuid), + pbxGroup = { + isa: 'PBXGroup', + children: [], + name: name, + path: path, + sourceTree: sourceTree ? sourceTree : '""' + }, + fileReferenceSection = this.pbxFileReferenceSection(), + filePathToReference = {}; + + for (var key in fileReferenceSection) { + // only look for comments + if (!COMMENT_KEY.test(key)) continue; + + var fileReferenceKey = key.split(COMMENT_KEY)[0], + fileReference = fileReferenceSection[fileReferenceKey]; + + filePathToReference[fileReference.path] = { fileRef: fileReferenceKey, basename: fileReferenceSection[key] }; + } + + for (var index = 0; index < filePathsArray.length; index++) { + var filePath = filePathsArray[index], + filePathQuoted = "\"" + filePath + "\""; + if (filePathToReference[filePath]) { + pbxGroup.children.push(pbxGroupChild(filePathToReference[filePath])); + continue; + } else if (filePathToReference[filePathQuoted]) { + pbxGroup.children.push(pbxGroupChild(filePathToReference[filePathQuoted])); + 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)); + } + + if (groups) { + groups[pbxGroupUuid] = pbxGroup; + groups[commentKey] = name; + } + + return { uuid: pbxGroupUuid, pbxGroup: pbxGroup }; +} + +pbxProject.prototype.removePbxGroup = function (groupName) { + var section = this.hash.project.objects['PBXGroup'], + key, itemKey; + + for (key in section) { + // only look for comments + if (!COMMENT_KEY.test(key)) continue; + + if (section[key] == groupName) { + itemKey = key.split(COMMENT_KEY)[0]; + delete section[itemKey]; + } + } +} + +pbxProject.prototype.addToPbxProjectSection = function(target) { + + var newTarget = { + value: target.uuid, + comment: pbxNativeTargetComment(target.pbxNativeTarget) + }; + + this.pbxProjectSection()[this.getFirstProject()['uuid']]['targets'].push(newTarget); +} + +pbxProject.prototype.addToPbxNativeTargetSection = function(target) { + var commentKey = f("%s_comment", target.uuid); + + this.pbxNativeTargetSection()[target.uuid] = target.pbxNativeTarget; + this.pbxNativeTargetSection()[commentKey] = target.pbxNativeTarget.name; +} + +pbxProject.prototype.addToPbxFileReferenceSection = function(file) { var commentKey = f("%s_comment", file.fileRef); this.pbxFileReferenceSection()[file.fileRef] = pbxFileReferenceObj(file); this.pbxFileReferenceSection()[commentKey] = pbxFileReferenceComment(file); } -pbxProject.prototype.removeFromPbxFileReferenceSection = function (file) { +pbxProject.prototype.removeFromPbxFileReferenceSection = function(file) { var i; var refObj = pbxFileReferenceObj(file); - for(i in this.pbxFileReferenceSection()) { - if(this.pbxFileReferenceSection()[i].name == refObj.name || - this.pbxFileReferenceSection()[i].path == refObj.path) { + for (i in this.pbxFileReferenceSection()) { + if (this.pbxFileReferenceSection()[i].name == refObj.name || + ('"' + this.pbxFileReferenceSection()[i].name + '"') == refObj.name || + this.pbxFileReferenceSection()[i].path == refObj.path || + ('"' + this.pbxFileReferenceSection()[i].path + '"') == refObj.path) { file.fileRef = file.uuid = i; delete this.pbxFileReferenceSection()[i]; break; } } var commentKey = f("%s_comment", file.fileRef); - if(this.pbxFileReferenceSection()[commentKey] != undefined) { + if (this.pbxFileReferenceSection()[commentKey] != undefined) { delete this.pbxFileReferenceSection()[commentKey]; } return file; } -pbxProject.prototype.addToPluginsPbxGroup = function (file) { +pbxProject.prototype.addToXcVersionGroupSection = function(file) { + if (!file.models || !file.currentModel) { + throw new Error("Cannot create a XCVersionGroup section from not a data model document file"); + } + + var commentKey = f("%s_comment", file.fileRef); + + if (!this.xcVersionGroupSection()[file.fileRef]) { + this.xcVersionGroupSection()[file.fileRef] = { + isa: 'XCVersionGroup', + children: file.models.map(function (el) { return el.fileRef; }), + currentVersion: file.currentModel.fileRef, + name: path.basename(file.path), + path: file.path, + sourceTree: '""', + versionGroupType: 'wrapper.xcdatamodel' + }; + this.xcVersionGroupSection()[commentKey] = path.basename(file.path); + } +} + +pbxProject.prototype.addToPluginsPbxGroup = function(file) { var pluginsGroup = this.pbxGroupByName('Plugins'); pluginsGroup.children.push(pbxGroupChild(file)); } -pbxProject.prototype.removeFromPluginsPbxGroup = function (file) { +pbxProject.prototype.removeFromPluginsPbxGroup = function(file) { var pluginsGroupChildren = this.pbxGroupByName('Plugins').children, i; - for(i in pluginsGroupChildren) { - if(pbxGroupChild(file).value == pluginsGroupChildren[i].value && - pbxGroupChild(file).comment == pluginsGroupChildren[i].comment) { + for (i in pluginsGroupChildren) { + if (pbxGroupChild(file).value == pluginsGroupChildren[i].value && + pbxGroupChild(file).comment == pluginsGroupChildren[i].comment) { pluginsGroupChildren.splice(i, 1); break; } } } -pbxProject.prototype.addToResourcesPbxGroup = function (file) { +pbxProject.prototype.addToResourcesPbxGroup = function(file) { var pluginsGroup = this.pbxGroupByName('Resources'); pluginsGroup.children.push(pbxGroupChild(file)); } -pbxProject.prototype.removeFromResourcesPbxGroup = function (file) { +pbxProject.prototype.removeFromResourcesPbxGroup = function(file) { var pluginsGroupChildren = this.pbxGroupByName('Resources').children, i; - for(i in pluginsGroupChildren) { - if(pbxGroupChild(file).value == pluginsGroupChildren[i].value && - pbxGroupChild(file).comment == pluginsGroupChildren[i].comment) { + for (i in pluginsGroupChildren) { + if (pbxGroupChild(file).value == pluginsGroupChildren[i].value && + pbxGroupChild(file).comment == pluginsGroupChildren[i].comment) { pluginsGroupChildren.splice(i, 1); break; } } } -pbxProject.prototype.addToFrameworksPbxGroup = function (file) { +pbxProject.prototype.addToFrameworksPbxGroup = function(file) { var pluginsGroup = this.pbxGroupByName('Frameworks'); pluginsGroup.children.push(pbxGroupChild(file)); } -pbxProject.prototype.removeFromFrameworksPbxGroup = function (file) { +pbxProject.prototype.removeFromFrameworksPbxGroup = function(file) { var pluginsGroupChildren = this.pbxGroupByName('Frameworks').children; - - for(i in pluginsGroupChildren) { - if(pbxGroupChild(file).value == pluginsGroupChildren[i].value && - pbxGroupChild(file).comment == pluginsGroupChildren[i].comment) { + + for (i in pluginsGroupChildren) { + if (pbxGroupChild(file).value == pluginsGroupChildren[i].value && + pbxGroupChild(file).comment == pluginsGroupChildren[i].comment) { pluginsGroupChildren.splice(i, 1); break; } } } -pbxProject.prototype.addToPbxSourcesBuildPhase = function (file) { - var sources = this.pbxSourcesBuildPhaseObj(); +pbxProject.prototype.addToPbxEmbedFrameworksBuildPhase = function (file) { + var sources = this.pbxEmbedFrameworksBuildPhaseObj(file.target); + if (sources) { + sources.files.push(pbxBuildPhaseObj(file)); + } +} + +pbxProject.prototype.removeFromPbxEmbedFrameworksBuildPhase = function (file) { + var sources = this.pbxEmbedFrameworksBuildPhaseObj(file.target); + if (sources) { + var files = []; + for (i in sources.files) { + if (sources.files[i].comment != longComment(file)) { + files.push(sources.files[i]); + } + } + sources.files = files; + } +} + +pbxProject.prototype.addToProductsPbxGroup = function(file) { + var productsGroup = this.pbxGroupByName('Products'); + productsGroup.children.push(pbxGroupChild(file)); +} + +pbxProject.prototype.removeFromProductsPbxGroup = function(file) { + var productsGroupChildren = this.pbxGroupByName('Products').children, i; + for (i in productsGroupChildren) { + if (pbxGroupChild(file).value == productsGroupChildren[i].value && + pbxGroupChild(file).comment == productsGroupChildren[i].comment) { + productsGroupChildren.splice(i, 1); + break; + } + } +} + +pbxProject.prototype.addToPbxSourcesBuildPhase = function(file) { + var sources = this.pbxSourcesBuildPhaseObj(file.target); sources.files.push(pbxBuildPhaseObj(file)); } -pbxProject.prototype.removeFromPbxSourcesBuildPhase = function (file) { - var sources = this.pbxSourcesBuildPhaseObj(), i; - for(i in sources.files) { - if(sources.files[i].comment == longComment(file)) { +pbxProject.prototype.removeFromPbxSourcesBuildPhase = function(file) { + + var sources = this.pbxSourcesBuildPhaseObj(file.target), i; + for (i in sources.files) { + if (sources.files[i].comment == longComment(file)) { sources.files.splice(i, 1); - break; + break; } } } -pbxProject.prototype.addToPbxResourcesBuildPhase = function (file) { - var sources = this.pbxResourcesBuildPhaseObj(); +pbxProject.prototype.addToPbxResourcesBuildPhase = function(file) { + var sources = this.pbxResourcesBuildPhaseObj(file.target); sources.files.push(pbxBuildPhaseObj(file)); } -pbxProject.prototype.removeFromPbxResourcesBuildPhase = function (file) { - var sources = this.pbxResourcesBuildPhaseObj(), i; +pbxProject.prototype.removeFromPbxResourcesBuildPhase = function(file) { + var sources = this.pbxResourcesBuildPhaseObj(file.target), i; - for(i in sources.files) { - if(sources.files[i].comment == longComment(file)) { + for (i in sources.files) { + if (sources.files[i].comment == longComment(file)) { sources.files.splice(i, 1); break; } } } -pbxProject.prototype.addToPbxFrameworksBuildPhase = function (file) { - var sources = this.pbxFrameworksBuildPhaseObj(); +pbxProject.prototype.addToPbxFrameworksBuildPhase = function(file) { + var sources = this.pbxFrameworksBuildPhaseObj(file.target); sources.files.push(pbxBuildPhaseObj(file)); } -pbxProject.prototype.removeFromPbxFrameworksBuildPhase = function (file) { - var sources = this.pbxFrameworksBuildPhaseObj(); - for(i in sources.files) { - if(sources.files[i].comment == longComment(file)) { +pbxProject.prototype.removeFromPbxFrameworksBuildPhase = function(file) { + var sources = this.pbxFrameworksBuildPhaseObj(file.target); + for (i in sources.files) { + if (sources.files[i].comment == longComment(file)) { sources.files.splice(i, 1); break; } } } +pbxProject.prototype.addXCConfigurationList = function(configurationObjectsArray, defaultConfigurationName, comment) { + var pbxBuildConfigurationSection = this.pbxXCBuildConfigurationSection(), + pbxXCConfigurationListSection = this.pbxXCConfigurationList(), + xcConfigurationListUuid = this.generateUuid(), + commentKey = f("%s_comment", xcConfigurationListUuid), + xcConfigurationList = { + isa: 'XCConfigurationList', + buildConfigurations: [], + defaultConfigurationIsVisible: 0, + defaultConfigurationName: defaultConfigurationName + }; + + for (var index = 0; index < configurationObjectsArray.length; index++) { + var configuration = configurationObjectsArray[index], + configurationUuid = this.generateUuid(), + configurationCommentKey = f("%s_comment", configurationUuid); + + pbxBuildConfigurationSection[configurationUuid] = configuration; + pbxBuildConfigurationSection[configurationCommentKey] = configuration.name; + xcConfigurationList.buildConfigurations.push({ value: configurationUuid, comment: configuration.name }); + } + + if (pbxXCConfigurationListSection) { + pbxXCConfigurationListSection[xcConfigurationListUuid] = xcConfigurationList; + pbxXCConfigurationListSection[commentKey] = comment; + } + + return { uuid: xcConfigurationListUuid, xcConfigurationList: xcConfigurationList }; +} + +pbxProject.prototype.addTargetDependency = function(target, dependencyTargets) { + if (!target) + return undefined; + + var nativeTargets = this.pbxNativeTargetSection(); + + if (typeof nativeTargets[target] == "undefined") + throw new Error("Invalid target: " + target); + + for (var index = 0; index < dependencyTargets.length; index++) { + var dependencyTarget = dependencyTargets[index]; + if (typeof nativeTargets[dependencyTarget] == "undefined") + throw new Error("Invalid target: " + dependencyTarget); + } + + var pbxTargetDependency = 'PBXTargetDependency', + pbxContainerItemProxy = 'PBXContainerItemProxy', + pbxTargetDependencySection = this.hash.project.objects[pbxTargetDependency], + pbxContainerItemProxySection = this.hash.project.objects[pbxContainerItemProxy]; + + for (var index = 0; index < dependencyTargets.length; index++) { + var dependencyTargetUuid = dependencyTargets[index], + dependencyTargetCommentKey = f("%s_comment", dependencyTargetUuid), + targetDependencyUuid = this.generateUuid(), + targetDependencyCommentKey = f("%s_comment", targetDependencyUuid), + itemProxyUuid = this.generateUuid(), + itemProxyCommentKey = f("%s_comment", itemProxyUuid), + itemProxy = { + isa: pbxContainerItemProxy, + containerPortal: this.hash.project['rootObject'], + containerPortal_comment: this.hash.project['rootObject_comment'], + proxyType: 1, + remoteGlobalIDString: dependencyTargetUuid, + remoteInfo: nativeTargets[dependencyTargetUuid].name + }, + targetDependency = { + isa: pbxTargetDependency, + target: dependencyTargetUuid, + target_comment: nativeTargets[dependencyTargetCommentKey], + targetProxy: itemProxyUuid, + targetProxy_comment: pbxContainerItemProxy + }; + + if (pbxContainerItemProxySection && pbxTargetDependencySection) { + pbxContainerItemProxySection[itemProxyUuid] = itemProxy; + pbxContainerItemProxySection[itemProxyCommentKey] = pbxContainerItemProxy; + pbxTargetDependencySection[targetDependencyUuid] = targetDependency; + pbxTargetDependencySection[targetDependencyCommentKey] = pbxTargetDependency; + nativeTargets[target].dependencies.push({ value: targetDependencyUuid, comment: pbxTargetDependency }) + } + } + + return { uuid: target, target: nativeTargets[target] }; +} + +pbxProject.prototype.addBuildPhase = function(filePathsArray, buildPhaseType, comment, target, optionsOrFolderType, subfolderPath) { + var buildPhaseSection, + fileReferenceSection = this.pbxFileReferenceSection(), + buildFileSection = this.pbxBuildFileSection(), + buildPhaseUuid = this.generateUuid(), + buildPhaseTargetUuid = target || this.getFirstTarget().uuid, + commentKey = f("%s_comment", buildPhaseUuid), + buildPhase = { + isa: buildPhaseType, + buildActionMask: 2147483647, + files: [], + runOnlyForDeploymentPostprocessing: 0 + }, + filePathToBuildFile = {}; + + if (buildPhaseType === 'PBXCopyFilesBuildPhase') { + buildPhase = pbxCopyFilesBuildPhaseObj(buildPhase, optionsOrFolderType, subfolderPath, comment); + } else if (buildPhaseType === 'PBXShellScriptBuildPhase') { + buildPhase = pbxShellScriptBuildPhaseObj(buildPhase, optionsOrFolderType, comment) + } + + if (!this.hash.project.objects[buildPhaseType]) { + this.hash.project.objects[buildPhaseType] = new Object(); + } + + if (!this.hash.project.objects[buildPhaseType][buildPhaseUuid]) { + this.hash.project.objects[buildPhaseType][buildPhaseUuid] = buildPhase; + this.hash.project.objects[buildPhaseType][commentKey] = comment; + } + + if (this.hash.project.objects['PBXNativeTarget'][buildPhaseTargetUuid]['buildPhases']) { + this.hash.project.objects['PBXNativeTarget'][buildPhaseTargetUuid]['buildPhases'].push({ + value: buildPhaseUuid, + comment: comment + }) + + } + + + for (var key in buildFileSection) { + // only look for comments + if (!COMMENT_KEY.test(key)) continue; + + var buildFileKey = key.split(COMMENT_KEY)[0], + buildFile = buildFileSection[buildFileKey]; + fileReference = fileReferenceSection[buildFile.fileRef]; + + if (!fileReference) continue; + + var pbxFileObj = new pbxFile(fileReference.path); + + filePathToBuildFile[fileReference.path] = { uuid: buildFileKey, basename: pbxFileObj.basename, group: pbxFileObj.group }; + } + + for (var index = 0; index < filePathsArray.length; index++) { + var filePath = filePathsArray[index], + filePathQuoted = "\"" + filePath + "\"", + file = new pbxFile(filePath); + + if (filePathToBuildFile[filePath]) { + buildPhase.files.push(pbxBuildPhaseObj(filePathToBuildFile[filePath])); + continue; + } else if (filePathToBuildFile[filePathQuoted]) { + buildPhase.files.push(pbxBuildPhaseObj(filePathToBuildFile[filePathQuoted])); + continue; + } + + file.uuid = this.generateUuid(); + file.fileRef = this.generateUuid(); + this.addToPbxFileReferenceSection(file); // PBXFileReference + this.addToPbxBuildFileSection(file); // PBXBuildFile + buildPhase.files.push(pbxBuildPhaseObj(file)); + } + + if (buildPhaseSection) { + buildPhaseSection[buildPhaseUuid] = buildPhase; + buildPhaseSection[commentKey] = comment; + } + + return { uuid: buildPhaseUuid, buildPhase: buildPhase }; +} + // helper access functions -pbxProject.prototype.pbxBuildFileSection = function () { +pbxProject.prototype.pbxProjectSection = function() { + return this.hash.project.objects['PBXProject']; +} +pbxProject.prototype.pbxBuildFileSection = function() { return this.hash.project.objects['PBXBuildFile']; } -pbxProject.prototype.pbxXCBuildConfigurationSection = function () { +pbxProject.prototype.pbxXCBuildConfigurationSection = function() { return this.hash.project.objects['XCBuildConfiguration']; } -pbxProject.prototype.pbxFileReferenceSection = function () { +pbxProject.prototype.pbxFileReferenceSection = function() { return this.hash.project.objects['PBXFileReference']; } -pbxProject.prototype.pbxGroupByName = function (name) { +pbxProject.prototype.pbxNativeTargetSection = function() { + return this.hash.project.objects['PBXNativeTarget']; +} + +pbxProject.prototype.xcVersionGroupSection = function () { + if (typeof this.hash.project.objects['XCVersionGroup'] !== 'object') { + this.hash.project.objects['XCVersionGroup'] = {}; + } + + return this.hash.project.objects['XCVersionGroup']; +} + +pbxProject.prototype.pbxXCConfigurationList = function() { + return this.hash.project.objects['XCConfigurationList']; +} + +pbxProject.prototype.pbxGroupByName = function(name) { var groups = this.hash.project.objects['PBXGroup'], key, groupKey; @@ -409,94 +954,503 @@ pbxProject.prototype.pbxGroupByName = function (name) { return null; } -pbxProject.prototype.pbxSourcesBuildPhaseObj = function () { - return this.buildPhaseObject('PBXSourcesBuildPhase', 'Sources'); +pbxProject.prototype.pbxTargetByName = function(name) { + return this.pbxItemByComment(name, 'PBXNativeTarget'); } -pbxProject.prototype.pbxResourcesBuildPhaseObj = function () { - return this.buildPhaseObject('PBXResourcesBuildPhase', 'Resources'); -} +pbxProject.prototype.findTargetKey = function(name) { + var targets = this.hash.project.objects['PBXNativeTarget']; + + for (var key in targets) { + // only look for comments + if (COMMENT_KEY.test(key)) continue; + + var target = targets[key]; + if (target.name === name) { + return key; + } + } -pbxProject.prototype.pbxFrameworksBuildPhaseObj = function () { - return this.buildPhaseObject('PBXFrameworksBuildPhase', 'Frameworks'); + return null; } -pbxProject.prototype.buildPhaseObject = function (name, group) { - var section = this.hash.project.objects[name], - obj, sectionKey, key; +pbxProject.prototype.pbxItemByComment = function(name, pbxSectionName) { + var section = this.hash.project.objects[pbxSectionName], + key, itemKey; for (key in section) { // only look for comments if (!COMMENT_KEY.test(key)) continue; - if (section[key] == group) { - sectionKey = key.split(COMMENT_KEY)[0]; - return section[sectionKey]; + if (section[key] == name) { + itemKey = key.split(COMMENT_KEY)[0]; + return section[itemKey]; } } return null; } -pbxProject.prototype.updateProductName = function(name) { - var config = this.pbxXCBuildConfigurationSection(); - propReplace(config, 'PRODUCT_NAME', '"' + name + '"'); +pbxProject.prototype.pbxSourcesBuildPhaseObj = function(target) { + return this.buildPhaseObject('PBXSourcesBuildPhase', 'Sources', target); } -pbxProject.prototype.ensureCorrectSearchPaths = function (file) { - var configurations = nonComments(this.pbxXCBuildConfigurationSection()), - INHERITED = '"$(inherited)"', - config, buildSettings, searchPaths; - - for (config in configurations) { - buildSettings = configurations[config].buildSettings; +pbxProject.prototype.pbxResourcesBuildPhaseObj = function(target) { + return this.buildPhaseObject('PBXResourcesBuildPhase', 'Resources', target); +} - if (unquote(buildSettings['PRODUCT_NAME']) != this.productName) - continue; +pbxProject.prototype.pbxFrameworksBuildPhaseObj = function(target) { + return this.buildPhaseObject('PBXFrameworksBuildPhase', 'Frameworks', target); +} - if (!buildSettings['LIBRARY_SEARCH_PATHS']) { - buildSettings['LIBRARY_SEARCH_PATHS'] = [INHERITED]; - } +pbxProject.prototype.pbxEmbedFrameworksBuildPhaseObj = function (target) { + return this.buildPhaseObject('PBXCopyFilesBuildPhase', 'Embed Frameworks', target); +}; - buildSettings['LIBRARY_SEARCH_PATHS'].push(searchPathForFile(file, this)); - } -} +// Find Build Phase from group/target +pbxProject.prototype.buildPhase = function(group, target) { -// a JS getter. hmmm -pbxProject.prototype.__defineGetter__("productName", function () { - var configurations = nonComments(this.pbxXCBuildConfigurationSection()), - config, productName; + if (!target) + return undefined; - for (config in configurations) { - productName = configurations[config].buildSettings['PRODUCT_NAME']; + var nativeTargets = this.pbxNativeTargetSection(); + if (typeof nativeTargets[target] == "undefined") + throw new Error("Invalid target: " + target); - if (productName) { - return unquote(productName); + var nativeTarget = nativeTargets[target]; + var buildPhases = nativeTarget.buildPhases; + for(var i in buildPhases) + { + var buildPhase = buildPhases[i]; + if (buildPhase.comment==group) + return buildPhase.value + "_comment"; } } -}); - -// check if file is present -pbxProject.prototype.hasFile = function (filePath) { - var files = nonComments(this.pbxFileReferenceSection()), - file, id; - for (id in files) { - file = files[id]; +pbxProject.prototype.buildPhaseObject = function(name, group, target) { + var section = this.hash.project.objects[name], + obj, sectionKey, key; + var buildPhase = this.buildPhase(group, target); - if (file.path == filePath) { - return true; - } - } + for (key in section) { + + // only look for comments + if (!COMMENT_KEY.test(key)) continue; + + // select the proper buildPhase + if (buildPhase && buildPhase!=key) + continue; + if (section[key] == group) { + sectionKey = key.split(COMMENT_KEY)[0]; + return section[sectionKey]; + } + } + return null; +} + +pbxProject.prototype.addBuildProperty = function(prop, value, build_name) { + var configurations = nonComments(this.pbxXCBuildConfigurationSection()), + key, configuration; + + for (key in configurations){ + configuration = configurations[key]; + if (!build_name || configuration.name === build_name){ + configuration.buildSettings[prop] = value; + } + } +} + +pbxProject.prototype.removeBuildProperty = function(prop, build_name) { + var configurations = nonComments(this.pbxXCBuildConfigurationSection()), + key, configuration; + + for (key in configurations){ + configuration = configurations[key]; + if (configuration.buildSettings[prop] && + !build_name || configuration.name === build_name){ + delete configuration.buildSettings[prop]; + } + } +} + +/** + * + * @param prop {String} + * @param value {String|Array|Object|Number|Boolean} + * @param build {String} Release or Debug + */ +pbxProject.prototype.updateBuildProperty = function(prop, value, build) { + var configs = this.pbxXCBuildConfigurationSection(); + for (var configName in configs) { + if (!COMMENT_KEY.test(configName)) { + var config = configs[configName]; + if ( (build && config.name === build) || (!build) ) { + config.buildSettings[prop] = value; + } + } + } +} + +pbxProject.prototype.updateProductName = function(name) { + this.updateBuildProperty('PRODUCT_NAME', '"' + name + '"'); +} + +pbxProject.prototype.removeFromFrameworkSearchPaths = function(file) { + var configurations = nonComments(this.pbxXCBuildConfigurationSection()), + INHERITED = '"$(inherited)"', + SEARCH_PATHS = 'FRAMEWORK_SEARCH_PATHS', + config, buildSettings, searchPaths; + var new_path = searchPathForFile(file, this); + + for (config in configurations) { + buildSettings = configurations[config].buildSettings; + + if (unquote(buildSettings['PRODUCT_NAME']) != this.productName) + continue; + + searchPaths = buildSettings[SEARCH_PATHS]; + + if (searchPaths) { + var matches = searchPaths.filter(function(p) { + return p.indexOf(new_path) > -1; + }); + matches.forEach(function(m) { + var idx = searchPaths.indexOf(m); + searchPaths.splice(idx, 1); + }); + } + } +} + +pbxProject.prototype.addToFrameworkSearchPaths = function(file) { + var configurations = nonComments(this.pbxXCBuildConfigurationSection()), + INHERITED = '"$(inherited)"', + config, buildSettings, searchPaths; + + for (config in configurations) { + buildSettings = configurations[config].buildSettings; + + if (unquote(buildSettings['PRODUCT_NAME']) != this.productName) + continue; + + if (!buildSettings['FRAMEWORK_SEARCH_PATHS'] + || buildSettings['FRAMEWORK_SEARCH_PATHS'] === INHERITED) { + buildSettings['FRAMEWORK_SEARCH_PATHS'] = [INHERITED]; + } + + buildSettings['FRAMEWORK_SEARCH_PATHS'].push(searchPathForFile(file, this)); + } +} + +pbxProject.prototype.removeFromLibrarySearchPaths = function(file) { + var configurations = nonComments(this.pbxXCBuildConfigurationSection()), + INHERITED = '"$(inherited)"', + SEARCH_PATHS = 'LIBRARY_SEARCH_PATHS', + config, buildSettings, searchPaths; + var new_path = searchPathForFile(file, this); + + for (config in configurations) { + buildSettings = configurations[config].buildSettings; + + if (unquote(buildSettings['PRODUCT_NAME']) != this.productName) + continue; + + searchPaths = buildSettings[SEARCH_PATHS]; + + if (searchPaths) { + var matches = searchPaths.filter(function(p) { + return p.indexOf(new_path) > -1; + }); + matches.forEach(function(m) { + var idx = searchPaths.indexOf(m); + searchPaths.splice(idx, 1); + }); + } + + } +} + +pbxProject.prototype.addToLibrarySearchPaths = function(file) { + var configurations = nonComments(this.pbxXCBuildConfigurationSection()), + INHERITED = '"$(inherited)"', + config, buildSettings, searchPaths; + + for (config in configurations) { + buildSettings = configurations[config].buildSettings; + + if (unquote(buildSettings['PRODUCT_NAME']) != this.productName) + continue; + + if (!buildSettings['LIBRARY_SEARCH_PATHS'] + || buildSettings['LIBRARY_SEARCH_PATHS'] === INHERITED) { + buildSettings['LIBRARY_SEARCH_PATHS'] = [INHERITED]; + } + + if (typeof file === 'string') { + buildSettings['LIBRARY_SEARCH_PATHS'].push(file); + } else { + buildSettings['LIBRARY_SEARCH_PATHS'].push(searchPathForFile(file, this)); + } + } +} + +pbxProject.prototype.removeFromHeaderSearchPaths = function(file) { + var configurations = nonComments(this.pbxXCBuildConfigurationSection()), + INHERITED = '"$(inherited)"', + SEARCH_PATHS = 'HEADER_SEARCH_PATHS', + config, buildSettings, searchPaths; + var new_path = searchPathForFile(file, this); + + for (config in configurations) { + buildSettings = configurations[config].buildSettings; + + if (unquote(buildSettings['PRODUCT_NAME']) != this.productName) + continue; + + if (buildSettings[SEARCH_PATHS]) { + var matches = buildSettings[SEARCH_PATHS].filter(function(p) { + return p.indexOf(new_path) > -1; + }); + matches.forEach(function(m) { + var idx = buildSettings[SEARCH_PATHS].indexOf(m); + buildSettings[SEARCH_PATHS].splice(idx, 1); + }); + } + + } +} +pbxProject.prototype.addToHeaderSearchPaths = function(file) { + var configurations = nonComments(this.pbxXCBuildConfigurationSection()), + INHERITED = '"$(inherited)"', + config, buildSettings, searchPaths; + + for (config in configurations) { + buildSettings = configurations[config].buildSettings; + + if (unquote(buildSettings['PRODUCT_NAME']) != this.productName) + continue; + + if (!buildSettings['HEADER_SEARCH_PATHS']) { + buildSettings['HEADER_SEARCH_PATHS'] = [INHERITED]; + } + + if (typeof file === 'string') { + buildSettings['HEADER_SEARCH_PATHS'].push(file); + } else { + buildSettings['HEADER_SEARCH_PATHS'].push(searchPathForFile(file, this)); + } + } +} + +pbxProject.prototype.addToOtherLinkerFlags = function (flag) { + var configurations = nonComments(this.pbxXCBuildConfigurationSection()), + INHERITED = '"$(inherited)"', + OTHER_LDFLAGS = 'OTHER_LDFLAGS', + config, buildSettings; + + for (config in configurations) { + buildSettings = configurations[config].buildSettings; + + if (unquote(buildSettings['PRODUCT_NAME']) != this.productName) + continue; + + if (!buildSettings[OTHER_LDFLAGS] + || buildSettings[OTHER_LDFLAGS] === INHERITED) { + buildSettings[OTHER_LDFLAGS] = [INHERITED]; + } + + buildSettings[OTHER_LDFLAGS].push(flag); + } +} + +pbxProject.prototype.removeFromOtherLinkerFlags = function (flag) { + var configurations = nonComments(this.pbxXCBuildConfigurationSection()), + OTHER_LDFLAGS = 'OTHER_LDFLAGS', + config, buildSettings; + + for (config in configurations) { + buildSettings = configurations[config].buildSettings; + + if (unquote(buildSettings['PRODUCT_NAME']) != this.productName) { + continue; + } + + if (buildSettings[OTHER_LDFLAGS]) { + var matches = buildSettings[OTHER_LDFLAGS].filter(function (p) { + return p.indexOf(flag) > -1; + }); + matches.forEach(function (m) { + var idx = buildSettings[OTHER_LDFLAGS].indexOf(m); + buildSettings[OTHER_LDFLAGS].splice(idx, 1); + }); + } + } +} + +pbxProject.prototype.addToBuildSettings = function (buildSetting, value) { + var configurations = nonComments(this.pbxXCBuildConfigurationSection()), + config, buildSettings; + + for (config in configurations) { + buildSettings = configurations[config].buildSettings; + + buildSettings[buildSetting] = value; + } +} + +pbxProject.prototype.removeFromBuildSettings = function (buildSetting) { + var configurations = nonComments(this.pbxXCBuildConfigurationSection()), + config, buildSettings; + + for (config in configurations) { + buildSettings = configurations[config].buildSettings; + + if (buildSettings[buildSetting]) { + delete buildSettings[buildSetting]; + } + } +} + +// a JS getter. hmmm +pbxProject.prototype.__defineGetter__("productName", function() { + var configurations = nonComments(this.pbxXCBuildConfigurationSection()), + config, productName; + + for (config in configurations) { + productName = configurations[config].buildSettings['PRODUCT_NAME']; + + if (productName) { + return unquote(productName); + } + } +}); + +// check if file is present +pbxProject.prototype.hasFile = function(filePath) { + var files = nonComments(this.pbxFileReferenceSection()), + file, id; + for (id in files) { + file = files[id]; + if (file.path == filePath || file.path == ('"' + filePath + '"')) { + return file; + } + } return false; } +pbxProject.prototype.addTarget = function(name, type, subfolder) { + + // Setup uuid and name of new target + var targetUuid = this.generateUuid(), + targetType = type, + targetSubfolder = subfolder || name, + targetName = name.trim(); + + // Check type against list of allowed target types + if (!targetName) { + throw new Error("Target name missing."); + } + + // Check type against list of allowed target types + if (!targetType) { + throw new Error("Target type missing."); + } + + // Check type against list of allowed target types + if (!producttypeForTargettype(targetType)) { + throw new Error("Target type invalid: " + targetType); + } + + // Build Configuration: Create + var buildConfigurationsList = [ + { + name: 'Debug', + isa: 'XCBuildConfiguration', + buildSettings: { + GCC_PREPROCESSOR_DEFINITIONS: ['"DEBUG=1"', '"$(inherited)"'], + INFOPLIST_FILE: '"' + path.join(targetSubfolder, targetSubfolder + '-Info.plist' + '"'), + LD_RUNPATH_SEARCH_PATHS: '"$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"', + PRODUCT_NAME: '"' + targetName + '"', + SKIP_INSTALL: 'YES' + } + }, + { + name: 'Release', + isa: 'XCBuildConfiguration', + buildSettings: { + INFOPLIST_FILE: '"' + path.join(targetSubfolder, targetSubfolder + '-Info.plist' + '"'), + LD_RUNPATH_SEARCH_PATHS: '"$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"', + PRODUCT_NAME: '"' + targetName + '"', + SKIP_INSTALL: 'YES' + } + } + ]; + + // Build Configuration: Add + var buildConfigurations = this.addXCConfigurationList(buildConfigurationsList, 'Release', 'Build configuration list for PBXNativeTarget "' + targetName +'"'); + + // Product: Create + var productName = targetName, + productType = producttypeForTargettype(targetType), + productFileType = filetypeForProducttype(productType), + productFile = this.addProductFile(productName, { group: 'Copy Files', 'target': targetUuid, 'explicitFileType': productFileType}), + productFileName = productFile.basename; + + + // Product: Add to build file list + this.addToPbxBuildFileSection(productFile); + + // Target: Create + var target = { + uuid: targetUuid, + pbxNativeTarget: { + isa: 'PBXNativeTarget', + name: '"' + targetName + '"', + productName: '"' + targetName + '"', + productReference: productFile.fileRef, + productType: '"' + producttypeForTargettype(targetType) + '"', + buildConfigurationList: buildConfigurations.uuid, + buildPhases: [], + buildRules: [], + dependencies: [] + } + }; + + // Target: Add to PBXNativeTarget section + this.addToPbxNativeTargetSection(target) + + // Product: Embed (only for "extension"-type targets) + if (targetType === 'app_extension') { + + // Create CopyFiles phase in first target + this.addBuildPhase([], 'PBXCopyFilesBuildPhase', 'Copy Files', this.getFirstTarget().uuid, targetType) + + // Add product to CopyFiles phase + this.addToPbxCopyfilesBuildPhase(productFile) + + // this.addBuildPhaseToTarget(newPhase.buildPhase, this.getFirstTarget().uuid) + + }; + + // Target: Add uuid to root project + this.addToPbxProjectSection(target); + + // Target: Add dependency for this target to first (main) target + this.addTargetDependency(this.getFirstTarget().uuid, [target.uuid]); + + + // Return target on success + return target; + +}; + // helper recursive prop search+replace function propReplace(obj, prop, value) { + var o = {}; for (var p in obj) { - if (obj.hasOwnProperty(p)) { - if (typeof obj[p] == 'object') { + if (o.hasOwnProperty.call(obj, p)) { + if (typeof obj[p] == 'object' && !Array.isArray(obj[p])) { propReplace(obj[p], prop, value); } else if (p == prop) { obj[p] = value; @@ -518,20 +1472,18 @@ function pbxBuildFileObj(file) { } function pbxFileReferenceObj(file) { - var obj = Object.create(null); - - obj.isa = 'PBXFileReference'; - obj.lastKnownFileType = file.lastType; - - obj.name = "\"" + file.basename + "\""; - obj.path = "\"" + file.path + "\""; - - obj.sourceTree = file.sourceTree; - - if (file.fileEncoding) - obj.fileEncoding = file.fileEncoding; - - return obj; + var fileObject = { + isa: "PBXFileReference", + name: "\"" + file.basename + "\"", + path: "\"" + file.path.replace(/\\/g, '/') + "\"", + sourceTree: file.sourceTree, + fileEncoding: file.fileEncoding, + lastKnownFileType: file.lastKnownFileType, + explicitFileType: file.explicitFileType, + includeInIndex: file.includeInIndex + }; + + return fileObject; } function pbxGroupChild(file) { @@ -552,12 +1504,63 @@ function pbxBuildPhaseObj(file) { return obj; } +function pbxCopyFilesBuildPhaseObj(obj, folderType, subfolderPath, phaseName) { + + // Add additional properties for 'CopyFiles' build phase + var DESTINATION_BY_TARGETTYPE = { + application: 'wrapper', + app_extension: 'plugins', + bundle: 'wrapper', + command_line_tool: 'wrapper', + dynamic_library: 'products_directory', + framework: 'shared_frameworks', + frameworks: 'frameworks', + static_library: 'products_directory', + unit_test_bundle: 'wrapper', + watch_app: 'wrapper', + watch_extension: 'plugins' + } + var SUBFOLDERSPEC_BY_DESTINATION = { + absolute_path: 0, + executables: 6, + frameworks: 10, + java_resources: 15, + plugins: 13, + products_directory: 16, + resources: 7, + shared_frameworks: 11, + shared_support: 12, + wrapper: 1, + xpc_services: 0 + } + + obj.name = '"' + phaseName + '"'; + obj.dstPath = subfolderPath || '""'; + obj.dstSubfolderSpec = SUBFOLDERSPEC_BY_DESTINATION[DESTINATION_BY_TARGETTYPE[folderType]]; + + return obj; +} + +function pbxShellScriptBuildPhaseObj(obj, options, phaseName) { + obj.name = '"' + phaseName + '"'; + obj.inputPaths = options.inputPaths || []; + obj.outputPaths = options.outputPaths || []; + obj.shellPath = options.shellPath; + obj.shellScript = '"' + options.shellScript.replace(/"/g, '\\"') + '"'; + + return obj; +} + function pbxBuildFileComment(file) { return longComment(file); } function pbxFileReferenceComment(file) { - return file.basename; + return file.basename || path.basename(file.path); +} + +function pbxNativeTargetComment(target) { + return target.name; } function longComment(file) { @@ -566,25 +1569,29 @@ function longComment(file) { // respect path function correctForPluginsPath(file, project) { - var r_plugin_dir = /^Plugins\//; + return correctForPath(file, project, 'Plugins'); +} - if (project.pbxGroupByName('Plugins').path) - file.path = file.path.replace(r_plugin_dir, ''); +function correctForResourcesPath(file, project) { + return correctForPath(file, project, 'Resources'); +} - return file; +function correctForFrameworksPath(file, project) { + return correctForPath(file, project, 'Frameworks'); } -function correctForResourcesPath(file, project) { - var r_resources_dir = /^Resources\//; +function correctForPath(file, project, group) { + var r_group_dir = new RegExp('^' + group + '[\\\\/]'); - if (project.pbxGroupByName('Resources').path) - file.path = file.path.replace(r_resources_dir, ''); + if (project.pbxGroupByName(group).path) + file.path = file.path.replace(r_group_dir, ''); return file; } function searchPathForFile(file, proj) { - var pluginsPath = proj.pbxGroupByName('Plugins').path, + var plugins = proj.pbxGroupByName('Plugins'), + pluginsPath = plugins ? plugins.path : null, fileDir = path.dirname(file.path); if (fileDir == '.') { @@ -595,6 +1602,8 @@ function searchPathForFile(file, proj) { if (file.plugin && pluginsPath) { return '"\\"$(SRCROOT)/' + unquote(pluginsPath) + '\\""'; + } else if (file.customFramework && file.dirname) { + return '"\\"' + file.dirname + '\\""'; } else { return '"\\"$(SRCROOT)/' + proj.productName + fileDir + '\\""'; } @@ -617,4 +1626,434 @@ function unquote(str) { if (str) return str.replace(/^"(.*)"$/, "$1"); } + +function buildPhaseNameForIsa (isa) { + + BUILDPHASENAME_BY_ISA = { + PBXCopyFilesBuildPhase: 'Copy Files', + PBXResourcesBuildPhase: 'Resources', + PBXSourcesBuildPhase: 'Sources', + PBXFrameworksBuildPhase: 'Frameworks' + } + + return BUILDPHASENAME_BY_ISA[isa] +} + +function producttypeForTargettype (targetType) { + + PRODUCTTYPE_BY_TARGETTYPE = { + application: 'com.apple.product-type.application', + app_extension: 'com.apple.product-type.app-extension', + bundle: 'com.apple.product-type.bundle', + command_line_tool: 'com.apple.product-type.tool', + dynamic_library: 'com.apple.product-type.library.dynamic', + framework: 'com.apple.product-type.framework', + static_library: 'com.apple.product-type.library.static', + unit_test_bundle: 'com.apple.product-type.bundle.unit-test', + watch_app: 'com.apple.product-type.application.watchapp', + watch_extension: 'com.apple.product-type.watchkit-extension' + }; + + return PRODUCTTYPE_BY_TARGETTYPE[targetType] +} + +function filetypeForProducttype (productType) { + + FILETYPE_BY_PRODUCTTYPE = { + 'com.apple.product-type.application': '"wrapper.application"', + 'com.apple.product-type.app-extension': '"wrapper.app-extension"', + 'com.apple.product-type.bundle': '"wrapper.plug-in"', + 'com.apple.product-type.tool': '"compiled.mach-o.dylib"', + 'com.apple.product-type.library.dynamic': '"compiled.mach-o.dylib"', + 'com.apple.product-type.framework': '"wrapper.framework"', + 'com.apple.product-type.library.static': '"archive.ar"', + 'com.apple.product-type.bundle.unit-test': '"wrapper.cfbundle"', + 'com.apple.product-type.application.watchapp': '"wrapper.application"', + 'com.apple.product-type.watchkit-extension': '"wrapper.app-extension"' + }; + + return FILETYPE_BY_PRODUCTTYPE[productType] +} + +pbxProject.prototype.getFirstProject = function() { + + // Get pbxProject container + var pbxProjectContainer = this.pbxProjectSection(); + + // Get first pbxProject UUID + var firstProjectUuid = Object.keys(pbxProjectContainer)[0]; + + // Get first pbxProject + var firstProject = pbxProjectContainer[firstProjectUuid]; + + return { + uuid: firstProjectUuid, + firstProject: firstProject + } +} + +pbxProject.prototype.getFirstTarget = function() { + + // Get first targets UUID + var firstTargetUuid = this.getFirstProject()['firstProject']['targets'][0].value; + + // Get first pbxNativeTarget + var firstTarget = this.pbxNativeTargetSection()[firstTargetUuid]; + + return { + uuid: firstTargetUuid, + firstTarget: firstTarget + } +} + +/*** NEW ***/ + +pbxProject.prototype.addToPbxGroupType = function (file, groupKey, groupType) { + var group = this.getPBXGroupByKeyAndType(groupKey, groupType); + if (group && group.children !== undefined) { + if (typeof file === 'string') { + //Group Key + var childGroup = { + value:file, + }; + if (this.getPBXGroupByKey(file)) { + childGroup.comment = this.getPBXGroupByKey(file).name; + } + else if (this.getPBXVariantGroupByKey(file)) { + childGroup.comment = this.getPBXVariantGroupByKey(file).name; + } + + group.children.push(childGroup); + } + else { + //File Object + group.children.push(pbxGroupChild(file)); + } + } +} + +pbxProject.prototype.addToPbxVariantGroup = function (file, groupKey) { + this.addToPbxGroupType(file, groupKey, 'PBXVariantGroup'); +} + +pbxProject.prototype.addToPbxGroup = function (file, groupKey) { + this.addToPbxGroupType(file, groupKey, 'PBXGroup'); +} + + + +pbxProject.prototype.pbxCreateGroupWithType = function(name, pathName, groupType) { + //Create object + var model = { + isa: '"' + groupType + '"', + children: [], + name: name, + sourceTree: '""' + }; + if (pathName) model.path = pathName; + var key = this.generateUuid(); + + //Create comment + var commendId = key + '_comment'; + + //add obj and commentObj to groups; + var groups = this.hash.project.objects[groupType]; + if (!groups) { + groups = this.hash.project.objects[groupType] = new Object(); + } + groups[commendId] = name; + groups[key] = model; + + return key; +} + +pbxProject.prototype.pbxCreateVariantGroup = function(name) { + return this.pbxCreateGroupWithType(name, undefined, 'PBXVariantGroup') +} + +pbxProject.prototype.pbxCreateGroup = function(name, pathName) { + return this.pbxCreateGroupWithType(name, pathName, 'PBXGroup'); +} + + + +pbxProject.prototype.removeFromPbxGroupAndType = function (file, groupKey, groupType) { + var group = this.getPBXGroupByKeyAndType(groupKey, groupType); + if (group) { + var groupChildren = group.children, i; + for(i in groupChildren) { + if(pbxGroupChild(file).value == groupChildren[i].value && + pbxGroupChild(file).comment == groupChildren[i].comment) { + groupChildren.splice(i, 1); + break; + } + } + } +} + +pbxProject.prototype.removeFromPbxGroup = function (file, groupKey) { + this.removeFromPbxGroupAndType(file, groupKey, 'PBXGroup'); +} + +pbxProject.prototype.removeFromPbxVariantGroup = function (file, groupKey) { + this.removeFromPbxGroupAndType(file, groupKey, 'PBXVariantGroup'); +} + + + +pbxProject.prototype.getPBXGroupByKeyAndType = function(key, groupType) { + return this.hash.project.objects[groupType][key]; +}; + +pbxProject.prototype.getPBXGroupByKey = function(key) { + return this.hash.project.objects['PBXGroup'][key]; +}; + +pbxProject.prototype.getPBXVariantGroupByKey = function(key) { + return this.hash.project.objects['PBXVariantGroup'][key]; +}; + + + +pbxProject.prototype.findPBXGroupKeyAndType = function(criteria, groupType) { + var groups = this.hash.project.objects[groupType]; + var target; + + for (var key in groups) { + // only look for comments + if (COMMENT_KEY.test(key)) continue; + + var group = groups[key]; + if (criteria && criteria.path && criteria.name) { + if (criteria.path === group.path && criteria.name === group.name) { + target = key; + break + } + } + else if (criteria && criteria.path) { + if (criteria.path === group.path) { + target = key; + break + } + } + else if (criteria && criteria.name) { + if (criteria.name === group.name) { + target = key; + break + } + } + } + + return target; +} + +pbxProject.prototype.findPBXGroupKey = function(criteria) { + return this.findPBXGroupKeyAndType(criteria, 'PBXGroup'); +} + +pbxProject.prototype.findPBXVariantGroupKey = function(criteria) { + return this.findPBXGroupKeyAndType(criteria, 'PBXVariantGroup'); +} + +pbxProject.prototype.addLocalizationVariantGroup = function(name) { + var groupKey = this.pbxCreateVariantGroup(name); + + var resourceGroupKey = this.findPBXGroupKey({name: 'Resources'}); + this.addToPbxGroup(groupKey, resourceGroupKey); + + var localizationVariantGroup = { + uuid: this.generateUuid(), + fileRef: groupKey, + basename: name + } + this.addToPbxBuildFileSection(localizationVariantGroup); // PBXBuildFile + this.addToPbxResourcesBuildPhase(localizationVariantGroup); //PBXResourcesBuildPhase + + return localizationVariantGroup; +}; + +pbxProject.prototype.addKnownRegion = function (name) { + if (!this.pbxProjectSection()[this.getFirstProject()['uuid']]['knownRegions']) { + this.pbxProjectSection()[this.getFirstProject()['uuid']]['knownRegions'] = []; + } + if (!this.hasKnownRegion(name)) { + this.pbxProjectSection()[this.getFirstProject()['uuid']]['knownRegions'].push(name); + } +} + +pbxProject.prototype.removeKnownRegion = function (name) { + var regions = this.pbxProjectSection()[this.getFirstProject()['uuid']]['knownRegions']; + if (regions) { + for (var i = 0; i < regions.length; i++) { + if (regions[i] === name) { + regions.splice(i, 1); + break; + } + } + this.pbxProjectSection()[this.getFirstProject()['uuid']]['knownRegions'] = regions; + } +} + +pbxProject.prototype.hasKnownRegion = function (name) { + var regions = this.pbxProjectSection()[this.getFirstProject()['uuid']]['knownRegions']; + if (regions) { + for (var i in regions) { + if (regions[i] === name) { + return true; + } + } + } + return false; +} + +pbxProject.prototype.getPBXObject = function(name) { + return this.hash.project.objects[name]; +} + + + +pbxProject.prototype.addFile = function (path, group, opt) { + var file = new pbxFile(path, opt); + + // null is better for early errors + if (this.hasFile(file.path)) return null; + + file.fileRef = this.generateUuid(); + + this.addToPbxFileReferenceSection(file); // PBXFileReference + + if (this.getPBXGroupByKey(group)) { + this.addToPbxGroup(file, group); // PBXGroup + } + else if (this.getPBXVariantGroupByKey(group)) { + this.addToPbxVariantGroup(file, group); // PBXVariantGroup + } + + return file; +} + +pbxProject.prototype.removeFile = function (path, group, opt) { + var file = new pbxFile(path, opt); + + this.removeFromPbxFileReferenceSection(file); // PBXFileReference + + if (this.getPBXGroupByKey(group)) { + this.removeFromPbxGroup(file, group); // PBXGroup + } + else if (this.getPBXVariantGroupByKey(group)) { + this.removeFromPbxVariantGroup(file, group); // PBXVariantGroup + } + + return file; +} + + + +pbxProject.prototype.getBuildProperty = function(prop, build) { + var target; + var configs = this.pbxXCBuildConfigurationSection(); + for (var configName in configs) { + if (!COMMENT_KEY.test(configName)) { + var config = configs[configName]; + if ( (build && config.name === build) || (build === undefined) ) { + if (config.buildSettings[prop] !== undefined) { + target = config.buildSettings[prop]; + } + } + } + } + return target; +} + +pbxProject.prototype.getBuildConfigByName = function(name) { + var target = {}; + var configs = this.pbxXCBuildConfigurationSection(); + for (var configName in configs) { + if (!COMMENT_KEY.test(configName)) { + var config = configs[configName]; + if (config.name === name) { + target[configName] = config; + } + } + } + return target; +} + +pbxProject.prototype.addDataModelDocument = function(filePath, group, opt) { + if (!group) { + group = 'Resources'; + } + if (!this.getPBXGroupByKey(group)) { + group = this.findPBXGroupKey({ name: group }); + } + + var file = new pbxFile(filePath, opt); + + if (!file || this.hasFile(file.path)) return null; + + file.fileRef = this.generateUuid(); + this.addToPbxGroup(file, group); + + if (!file) return false; + + file.target = opt ? opt.target : undefined; + file.uuid = this.generateUuid(); + + this.addToPbxBuildFileSection(file); + this.addToPbxSourcesBuildPhase(file); + + file.models = []; + var currentVersionName; + var modelFiles = fs.readdirSync(file.path); + for (var index in modelFiles) { + var modelFileName = modelFiles[index]; + var modelFilePath = path.join(filePath, modelFileName); + + if (modelFileName == '.xccurrentversion') { + currentVersionName = plist.readFileSync(modelFilePath)._XCCurrentVersionName; + continue; + } + + var modelFile = new pbxFile(modelFilePath); + modelFile.fileRef = this.generateUuid(); + + this.addToPbxFileReferenceSection(modelFile); + + file.models.push(modelFile); + + if (currentVersionName && currentVersionName === modelFileName) { + file.currentModel = modelFile; + } + } + + if (!file.currentModel) { + file.currentModel = file.models[0]; + } + + this.addToXcVersionGroupSection(file); + + return file; +} + +pbxProject.prototype.addTargetAttribute = function(prop, value, target) { + var attributes = this.getFirstProject()['firstProject']['attributes']; + if (attributes['TargetAttributes'] === undefined) { + attributes['TargetAttributes'] = {}; + } + target = target || this.getFirstTarget(); + if (attributes['TargetAttributes'][target.uuid] === undefined) { + attributes['TargetAttributes'][target.uuid] = {}; + } + attributes['TargetAttributes'][target.uuid][prop] = value; +} + +pbxProject.prototype.removeTargetAttribute = function(prop, target) { + var attributes = this.getFirstProject()['firstProject']['attributes']; + target = target || this.getFirstTarget(); + if (attributes['TargetAttributes'] && + attributes['TargetAttributes'][target.uuid]) { + delete attributes['TargetAttributes'][target.uuid][prop]; + } +} + module.exports = pbxProject; diff --git a/package.json b/package.json index 4d01488..f0841b1 100644 --- a/package.json +++ b/package.json @@ -1,23 +1,49 @@ { - "author": "Andrew Lunny ", + "author": "Apache Software Foundation", "name": "xcode", "description": "parser for xcodeproj/project.pbxproj files", - "version": "0.6.0", - "main":"index.js", + "version": "0.9.3", + "main": "index.js", "repository": { - "url": "https://github.com/alunny/node-xcode.git" + "url": "https://github.com/apache/cordova-node-xcode.git" }, "engines": { "node": ">=0.6.7" }, "dependencies": { - "pegjs":"0.6.2", - "node-uuid":"1.3.3" + "pegjs": "^0.10.0", + "simple-plist": "^0.2.1", + "uuid": "3.0.1" }, "devDependencies": { - "nodeunit":"0.6.4" + "nodeunit": "^0.11.0" }, "scripts": { "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" + } + + ] + } diff --git a/test/BuildSettings.js b/test/BuildSettings.js new file mode 100644 index 0000000..0d940a4 --- /dev/null +++ b/test/BuildSettings.js @@ -0,0 +1,41 @@ +var fullProject = require('./fixtures/full-project') + fullProjectStr = JSON.stringify(fullProject), + pbx = require('../lib/pbxProject'), + pbxFile = require('../lib/pbxFile'), + proj = new pbx('.'); + +function cleanHash() { + return JSON.parse(fullProjectStr); +} + +exports.setUp = function (callback) { + proj.hash = cleanHash(); + callback(); +} + +var PRODUCT_NAME = '"KitchenSinktablet"'; + +exports.addAndRemoveToFromBuildSettings = { + 'add should add the build setting to each configuration section':function(test) { + var buildSetting = 'some/buildSetting'; + var value = 'some/buildSetting'; + proj.addToBuildSettings(buildSetting, value); + var config = proj.pbxXCBuildConfigurationSection(); + for (var ref in config) { + if (ref.indexOf('_comment') > -1 || config[ref].buildSettings.PRODUCT_NAME != PRODUCT_NAME) continue; + test.ok(config[ref].buildSettings[buildSetting] === value); + } + test.done(); + }, + 'remove should remove from the build settings in each configuration section':function(test) { + var buildSetting = 'some/buildSetting'; + proj.addToBuildSettings(buildSetting, 'some/buildSetting'); + proj.removeFromBuildSettings(buildSetting); + var config = proj.pbxXCBuildConfigurationSection(); + for (var ref in config) { + if (ref.indexOf('_comment') > -1 || config[ref].buildSettings.PRODUCT_NAME != PRODUCT_NAME) continue; + test.ok(!config[ref].buildSettings.hasOwnProperty(buildSetting)); + } + test.done(); + } +} diff --git a/test/FrameworkSearchPaths.js b/test/FrameworkSearchPaths.js new file mode 100644 index 0000000..d717416 --- /dev/null +++ b/test/FrameworkSearchPaths.js @@ -0,0 +1,46 @@ +var fullProject = require('./fixtures/full-project') + fullProjectStr = JSON.stringify(fullProject), + pbx = require('../lib/pbxProject'), + pbxFile = require('../lib/pbxFile'), + proj = new pbx('.'); + +var pbxFile = { + path:'some/path/include', + dirname: 'some/path', + customFramework: true +} +function cleanHash() { + return JSON.parse(fullProjectStr); +} + +exports.setUp = function (callback) { + proj.hash = cleanHash(); + callback(); +} + +var PRODUCT_NAME = '"KitchenSinktablet"'; + +exports.addAndRemoveToFromFrameworkSearchPaths = { + 'add should add the path to each configuration section':function(test) { + proj.addToFrameworkSearchPaths(pbxFile); + var config = proj.pbxXCBuildConfigurationSection(); + for (var ref in config) { + if (ref.indexOf('_comment') > -1 || config[ref].buildSettings.PRODUCT_NAME != PRODUCT_NAME) continue; + var lib = config[ref].buildSettings.FRAMEWORK_SEARCH_PATHS; + test.ok(lib[1].indexOf('some/path') > -1); + } + test.done(); + }, + 'remove should remove from the path to each configuration section':function(test) { + proj.addToFrameworkSearchPaths(pbxFile); + proj.removeFromFrameworkSearchPaths(pbxFile); + var config = proj.pbxXCBuildConfigurationSection(); + for (var ref in config) { + if (ref.indexOf('_comment') > -1 || config[ref].buildSettings.PRODUCT_NAME != PRODUCT_NAME) continue; + var lib = config[ref].buildSettings.FRAMEWORK_SEARCH_PATHS; + test.ok(lib.length === 1); + test.ok(lib[0].indexOf('some/path') == -1); + } + test.done(); + } +} diff --git a/test/HeaderSearchPaths.js b/test/HeaderSearchPaths.js new file mode 100644 index 0000000..15d1292 --- /dev/null +++ b/test/HeaderSearchPaths.js @@ -0,0 +1,59 @@ +var fullProject = require('./fixtures/full-project') + fullProjectStr = JSON.stringify(fullProject), + pbx = require('../lib/pbxProject'), + pbxFile = require('../lib/pbxFile'), + proj = new pbx('.'); + +function cleanHash() { + return JSON.parse(fullProjectStr); +} + +exports.setUp = function (callback) { + proj.hash = cleanHash(); + callback(); +} + +var PRODUCT_NAME = '"KitchenSinktablet"'; + +exports.addAndRemoveToFromHeaderSearchPaths = { + 'add should add the path to each configuration section':function(test) { + proj.addToHeaderSearchPaths({ + path:'some/path/include' + }); + var config = proj.pbxXCBuildConfigurationSection(); + for (var ref in config) { + if (ref.indexOf('_comment') > -1 || config[ref].buildSettings.PRODUCT_NAME != PRODUCT_NAME) continue; + var lib = config[ref].buildSettings.HEADER_SEARCH_PATHS; + test.ok(lib[1].indexOf('$(SRCROOT)/KitchenSinktablet/some/path') > -1); + } + test.done(); + }, + 'add should not mangle string arguments and add to each config section':function(test) { + var includePath = '../../some/path'; + proj.addToHeaderSearchPaths(includePath); + var config = proj.pbxXCBuildConfigurationSection(); + for (var ref in config) { + if (ref.indexOf('_comment') > -1 || config[ref].buildSettings.PRODUCT_NAME != PRODUCT_NAME) continue; + var lib = config[ref].buildSettings.HEADER_SEARCH_PATHS; + test.ok(lib[1].indexOf(includePath) > -1); + } + test.done(); + }, + 'remove should remove from the path to each configuration section':function(test) { + var libPath = 'some/path/include'; + proj.addToHeaderSearchPaths({ + path:libPath + }); + proj.removeFromHeaderSearchPaths({ + path:libPath + }); + var config = proj.pbxXCBuildConfigurationSection(); + for (var ref in config) { + if (ref.indexOf('_comment') > -1 || config[ref].buildSettings.PRODUCT_NAME != PRODUCT_NAME) continue; + var lib = config[ref].buildSettings.HEADER_SEARCH_PATHS; + test.ok(lib.length === 1); + test.ok(lib[0].indexOf('$(SRCROOT)/KitchenSinktablet/some/path/include') == -1); + } + test.done(); + } +} diff --git a/test/LibrarySearchPaths.js b/test/LibrarySearchPaths.js new file mode 100644 index 0000000..8f9dd68 --- /dev/null +++ b/test/LibrarySearchPaths.js @@ -0,0 +1,59 @@ +var fullProject = require('./fixtures/full-project') + fullProjectStr = JSON.stringify(fullProject), + pbx = require('../lib/pbxProject'), + pbxFile = require('../lib/pbxFile'), + proj = new pbx('.'); + +function cleanHash() { + return JSON.parse(fullProjectStr); +} + +exports.setUp = function (callback) { + proj.hash = cleanHash(); + callback(); +} + +var PRODUCT_NAME = '"KitchenSinktablet"'; + +exports.addAndRemoveToFromLibrarySearchPaths = { + 'add should add the path to each configuration section':function(test) { + proj.addToLibrarySearchPaths({ + path:'some/path/poop.a' + }); + var config = proj.pbxXCBuildConfigurationSection(); + for (var ref in config) { + if (ref.indexOf('_comment') > -1 || config[ref].buildSettings.PRODUCT_NAME != PRODUCT_NAME) continue; + var lib = config[ref].buildSettings.LIBRARY_SEARCH_PATHS; + test.ok(lib[1].indexOf('$(SRCROOT)/KitchenSinktablet/some/path') > -1); + } + test.done(); + }, + 'add should not mangle string arguments and add to each config section':function(test) { + var libPath = '../../some/path'; + proj.addToLibrarySearchPaths(libPath); + var config = proj.pbxXCBuildConfigurationSection(); + for (var ref in config) { + if (ref.indexOf('_comment') > -1 || config[ref].buildSettings.PRODUCT_NAME != PRODUCT_NAME) continue; + var lib = config[ref].buildSettings.LIBRARY_SEARCH_PATHS; + test.ok(lib[1].indexOf(libPath) > -1); + } + test.done(); + }, + 'remove should remove from the path to each configuration section':function(test) { + var libPath = 'some/path/poop.a'; + proj.addToLibrarySearchPaths({ + path:libPath + }); + proj.removeFromLibrarySearchPaths({ + path:libPath + }); + var config = proj.pbxXCBuildConfigurationSection(); + for (var ref in config) { + if (ref.indexOf('_comment') > -1 || config[ref].buildSettings.PRODUCT_NAME != PRODUCT_NAME) continue; + var lib = config[ref].buildSettings.LIBRARY_SEARCH_PATHS; + test.ok(lib.length === 1); + test.ok(lib[0].indexOf('$(SRCROOT)/KitchenSinktablet/some/path') == -1); + } + test.done(); + } +} diff --git a/test/OtherLinkerFlags.js b/test/OtherLinkerFlags.js new file mode 100644 index 0000000..ad99c8d --- /dev/null +++ b/test/OtherLinkerFlags.js @@ -0,0 +1,43 @@ +var fullProject = require('./fixtures/full-project') + fullProjectStr = JSON.stringify(fullProject), + pbx = require('../lib/pbxProject'), + pbxFile = require('../lib/pbxFile'), + proj = new pbx('.'); + +function cleanHash() { + return JSON.parse(fullProjectStr); +} + +exports.setUp = function (callback) { + proj.hash = cleanHash(); + callback(); +} + +var PRODUCT_NAME = '"KitchenSinktablet"'; + +exports.addAndRemoveToFromOtherLinkerFlags = { + 'add should add the flag to each configuration section':function(test) { + var flag = 'some/flag'; + proj.addToOtherLinkerFlags(flag); + var config = proj.pbxXCBuildConfigurationSection(); + for (var ref in config) { + if (ref.indexOf('_comment') > -1 || config[ref].buildSettings.PRODUCT_NAME != PRODUCT_NAME) continue; + var lib = config[ref].buildSettings.OTHER_LDFLAGS; + test.ok(lib[1].indexOf(flag) > -1); + } + test.done(); + }, + 'remove should remove from the path to each configuration section':function(test) { + var flag = 'some/flag'; + proj.addToOtherLinkerFlags(flag); + proj.removeFromOtherLinkerFlags(flag); + var config = proj.pbxXCBuildConfigurationSection(); + for (var ref in config) { + if (ref.indexOf('_comment') > -1 || config[ref].buildSettings.PRODUCT_NAME != PRODUCT_NAME) continue; + var lib = config[ref].buildSettings.OTHER_LDFLAGS; + test.ok(lib.length === 1); + test.ok(lib[0].indexOf(flag) == -1); + } + test.done(); + } +} diff --git a/test/addBuildPhase.js b/test/addBuildPhase.js new file mode 100644 index 0000000..f5dd27c --- /dev/null +++ b/test/addBuildPhase.js @@ -0,0 +1,120 @@ +var fullProject = require('./fixtures/full-project') + fullProjectStr = JSON.stringify(fullProject), + pbx = require('../lib/pbxProject'), + proj = new pbx('.'); + +function cleanHash() { + return JSON.parse(fullProjectStr); +} + +exports.setUp = function (callback) { + proj.hash = cleanHash(); + callback(); +} + +exports.addBuildPhase = { + 'should return a pbxBuildPhase': function (test) { + var buildPhase = proj.addBuildPhase(['file.m'], 'PBXSourcesBuildPhase', 'My build phase'); + + test.ok(typeof buildPhase === 'object'); + test.done() + }, + 'should set a uuid on the pbxBuildPhase': function (test) { + var buildPhase = proj.addBuildPhase(['file.m'], 'PBXSourcesBuildPhase', 'My build phase'); + + test.ok(buildPhase.uuid); + test.done() + }, + 'should add all files to build phase': function (test) { + var buildPhase = proj.addBuildPhase(['file.m', 'assets.bundle'], 'PBXResourcesBuildPhase', 'My build phase').buildPhase; + for (var index = 0; index < buildPhase.files.length; index++) { + var file = buildPhase.files[index]; + test.ok(file.value); + } + + test.done() + }, + 'should add the PBXBuildPhase object correctly': function (test) { + var buildPhase = proj.addBuildPhase(['file.m', 'assets.bundle'], 'PBXResourcesBuildPhase', 'My build phase').buildPhase, + buildPhaseInPbx = proj.buildPhaseObject('PBXResourcesBuildPhase', 'My build phase'); + + test.equal(buildPhaseInPbx, buildPhase); + test.equal(buildPhaseInPbx.isa, 'PBXResourcesBuildPhase'); + test.equal(buildPhaseInPbx.buildActionMask, 2147483647); + test.equal(buildPhaseInPbx.runOnlyForDeploymentPostprocessing, 0); + test.done(); + }, + 'should add each of the files to PBXBuildFile section': function (test) { + var buildPhase = proj.addBuildPhase(['file.m', 'assets.bundle'], 'PBXResourcesBuildPhase', 'My build phase').buildPhase, + buildFileSection = proj.pbxBuildFileSection(); + + for (var index = 0; index < buildPhase.files.length; index++) { + var file = buildPhase.files[index]; + test.ok(buildFileSection[file.value]); + } + + test.done(); + }, + 'should add each of the files to PBXFileReference section': function (test) { + var buildPhase = proj.addBuildPhase(['file.m', 'assets.bundle'], 'PBXResourcesBuildPhase', 'My build phase').buildPhase, + fileRefSection = proj.pbxFileReferenceSection(), + buildFileSection = proj.pbxBuildFileSection(), + fileRefs = []; + + for (var index = 0; index < buildPhase.files.length; index++) { + var file = buildPhase.files[index], + fileRef = buildFileSection[file.value].fileRef; + + test.ok(fileRefSection[fileRef]); + } + + test.done(); + }, + 'should not add files to PBXFileReference section if already added': function (test) { + var fileRefSection = proj.pbxFileReferenceSection(), + initialFileReferenceSectionItemsCount = Object.keys(fileRefSection), + buildPhase = proj.addBuildPhase(['AppDelegate.m', 'main.m'], 'PBXResourcesBuildPhase', 'My build phase').buildPhase, + afterAdditionBuildFileSectionItemsCount = Object.keys(fileRefSection); + + test.deepEqual(initialFileReferenceSectionItemsCount, afterAdditionBuildFileSectionItemsCount); + test.done(); + }, + 'should not add files to PBXBuildFile section if already added': function (test) { + var buildFileSection = proj.pbxBuildFileSection(), + initialBuildFileSectionItemsCount = Object.keys(buildFileSection), + buildPhase = proj.addBuildPhase(['AppDelegate.m', 'main.m'], 'PBXResourcesBuildPhase', 'My build phase').buildPhase, + afterAdditionBuildFileSectionItemsCount = Object.keys(buildFileSection); + + test.deepEqual(initialBuildFileSectionItemsCount, afterAdditionBuildFileSectionItemsCount); + test.done(); + }, + 'should add only missing files to PBXFileReference section': function (test) { + var fileRefSection = proj.pbxFileReferenceSection(), + buildFileSection = proj.pbxBuildFileSection(), + initialFileReferenceSectionItemsCount = Object.keys(fileRefSection), + buildPhase = proj.addBuildPhase(['file.m', 'AppDelegate.m'], 'PBXResourcesBuildPhase', 'My build phase').buildPhase, + afterAdditionBuildFileSectionItemsCount = Object.keys(fileRefSection); + + for (var index = 0; index < buildPhase.files.length; index++) { + var file = buildPhase.files[index], + fileRef = buildFileSection[file.value].fileRef; + + test.ok(fileRefSection[fileRef]); + } + + test.deepEqual(initialFileReferenceSectionItemsCount.length, afterAdditionBuildFileSectionItemsCount.length - 2); + test.done(); + }, + 'should set target to Frameworks given \'frameworks\' as target': function (test) { + var buildPhase = proj.addBuildPhase(['file.m'], 'PBXCopyFilesBuildPhase', 'Copy Files', proj.getFirstTarget().uuid, 'frameworks').buildPhase; + test.equal(buildPhase.dstSubfolderSpec, 10); + test.done(); + }, + 'should add a script build phase to echo "hello world!"': function(test) { + var options = {shellPath: '/bin/sh', shellScript: 'echo "hello world!"'}; + var buildPhase = proj.addBuildPhase([], 'PBXShellScriptBuildPhase', 'Run a script', proj.getFirstTarget().uuid, options).buildPhase; + test.equal(buildPhase.shellPath, '/bin/sh'); + test.equal(buildPhase.shellScript, '"echo \\"hello world!\\""'); + test.done(); + }, +} diff --git a/test/addFramework.js b/test/addFramework.js index 0c6e19c..d7e1c2b 100644 --- a/test/addFramework.js +++ b/test/addFramework.js @@ -13,6 +13,35 @@ exports.setUp = function (callback) { callback(); } +function nonComments(obj) { + var keys = Object.keys(obj), + newObj = {}, i = 0; + + for (i; i < keys.length; i++) { + if (!/_comment$/.test(keys[i])) { + newObj[keys[i]] = obj[keys[i]]; + } + } + + return newObj; +} + +function frameworkSearchPaths(proj) { + var configs = nonComments(proj.pbxXCBuildConfigurationSection()), + allPaths = [], + ids = Object.keys(configs), i, buildSettings; + + for (i = 0; i< ids.length; i++) { + buildSettings = configs[ids[i]].buildSettings; + + if (buildSettings['FRAMEWORK_SEARCH_PATHS']) { + allPaths.push(buildSettings['FRAMEWORK_SEARCH_PATHS']); + } + } + + return allPaths; +} + exports.addFramework = { 'should return a pbxFile': function (test) { var newFile = proj.addFramework('libsqlite3.dylib'); @@ -51,7 +80,7 @@ exports.addFramework = { fileRefEntry = fileRefSection[newFile.fileRef]; test.equal(fileRefEntry.isa, 'PBXFileReference'); - test.equal(fileRefEntry.lastKnownFileType, '"compiled.mach-o.dylib"'); + test.equal(fileRefEntry.lastKnownFileType, 'compiled.mach-o.dylib'); test.equal(fileRefEntry.name, '"libsqlite3.dylib"'); test.equal(fileRefEntry.path, '"usr/lib/libsqlite3.dylib"'); test.equal(fileRefEntry.sourceTree, 'SDKROOT'); @@ -98,7 +127,7 @@ exports.addFramework = { test.equal(buildFileEntry.fileRef, newFile.fileRef); test.equal(buildFileEntry.fileRef_comment, 'libsqlite3.dylib'); test.deepEqual(buildFileEntry.settings, { ATTRIBUTES: [ 'Weak' ] }); - + test.done(); }, 'should add to the Frameworks PBXGroup': function (test) { @@ -125,6 +154,13 @@ exports.addFramework = { test.equal(frameworks.files.length, 16); test.done(); }, + 'should not add to the PBXFrameworksBuildPhase': function (test) { + var newFile = proj.addFramework('Private.framework', {link: false}), + frameworks = proj.pbxFrameworksBuildPhaseObj(); + + test.equal(frameworks.files.length, 15); + test.done(); + }, 'should have the right values for the Sources entry': function (test) { var newFile = proj.addFramework('libsqlite3.dylib'), frameworks = proj.pbxFrameworksBuildPhaseObj(), @@ -141,5 +177,59 @@ exports.addFramework = { test.ok(!proj.addFramework('libsqlite3.dylib')); test.done(); } - } + }, + 'should pbxFile correctly for custom frameworks': function (test) { + var newFile = proj.addFramework('/path/to/Custom.framework', {customFramework: true}); + + test.ok(newFile.customFramework); + test.ok(!newFile.fileEncoding); + test.equal(newFile.sourceTree, '""'); + test.equal(newFile.group, 'Frameworks'); + test.equal(newFile.basename, 'Custom.framework'); + test.equal(newFile.dirname, '/path/to'); + // XXX framework has to be copied over to PROJECT root. That is what XCode does when you drag&drop + test.equal(newFile.path, '/path/to/Custom.framework'); + + + // should add path to framework search path + var frameworkPaths = frameworkSearchPaths(proj); + expectedPath = '"\\"/path/to\\""'; + + for (i = 0; i < frameworkPaths.length; i++) { + var current = frameworkPaths[i]; + test.ok(current.indexOf('"$(inherited)"') >= 0); + test.ok(current.indexOf(expectedPath) >= 0); + } + test.done(); + }, + 'should add to the Embed Frameworks PBXCopyFilesBuildPhase': function (test) { + var newFile = proj.addFramework('/path/to/SomeEmbeddableCustom.framework', {customFramework: true, embed: true}), + frameworks = proj.pbxEmbedFrameworksBuildPhaseObj(); + + var buildPhaseInPbx = proj.pbxEmbedFrameworksBuildPhaseObj(); + test.equal(buildPhaseInPbx.dstSubfolderSpec, 10); + + test.equal(frameworks.files.length, 1); + test.done(); + }, + 'should not add to the Embed Frameworks PBXCopyFilesBuildPhase by default': function (test) { + var newFile = proj.addFramework('/path/to/Custom.framework', {customFramework: true}), + frameworks = proj.pbxEmbedFrameworksBuildPhaseObj(); + + test.equal(frameworks.files.length, 0); + test.done(); + }, + 'should add the PBXBuildFile object correctly /w signable frameworks': function (test) { + var newFile = proj.addFramework('/path/to/SomeSignable.framework', { customFramework: true, embed: true, sign: true }), + buildFileSection = proj.pbxBuildFileSection(), + buildFileEntry = buildFileSection[newFile.uuid]; + + test.equal(newFile.group, 'Embed Frameworks'); + test.equal(buildFileEntry.isa, 'PBXBuildFile'); + test.equal(buildFileEntry.fileRef, newFile.fileRef); + test.equal(buildFileEntry.fileRef_comment, 'SomeSignable.framework'); + test.deepEqual(buildFileEntry.settings, { ATTRIBUTES: [ 'CodeSignOnCopy' ] }); + + test.done(); + }, } diff --git a/test/addRemovePbxGroup.js b/test/addRemovePbxGroup.js new file mode 100644 index 0000000..7c6e978 --- /dev/null +++ b/test/addRemovePbxGroup.js @@ -0,0 +1,160 @@ +var fullProject = require('./fixtures/full-project') + fullProjectStr = JSON.stringify(fullProject), + pbx = require('../lib/pbxProject'), + proj = new pbx('.'); + +function cleanHash() { + return JSON.parse(fullProjectStr); +} + +exports.setUp = function (callback) { + proj.hash = cleanHash(); + callback(); +} + +exports.addRemovePbxGroup = { + 'should return a pbxGroup': function (test) { + var pbxGroup = proj.addPbxGroup(['file.m'], 'MyGroup', 'Application', 'Application', '""'); + + test.ok(typeof pbxGroup === 'object'); + test.done() + }, + 'should set a uuid on the pbxGroup': function (test) { + var pbxGroup = proj.addPbxGroup(['file.m'], 'MyGroup', 'Application', 'Application', '""'); + + test.ok(pbxGroup.uuid); + test.done() + }, + 'should add all files to pbxGroup': function (test) { + var pbxGroup = proj.addPbxGroup(['file.m'], 'MyGroup', 'Application', 'Application', '""'); + for (var index = 0; index < pbxGroup.pbxGroup.children.length; index++) { + var file = pbxGroup.pbxGroup.children[index]; + test.ok(file.value); + } + + test.done() + }, + 'should add the PBXGroup object correctly': function (test) { + var pbxGroup = proj.addPbxGroup(['file.m'], 'MyGroup', 'Application', '""'); + pbxGroupInPbx = proj.pbxGroupByName('MyGroup'); + + test.equal(pbxGroupInPbx.children, pbxGroup.pbxGroup.children); + test.equal(pbxGroupInPbx.isa, 'PBXGroup'); + test.equal(pbxGroupInPbx.path, 'Application'); + test.equal(pbxGroupInPbx.sourceTree, '""'); + test.done(); + }, + 'should add sourceTree if no other specified': function (test) { + var pbxGroup = proj.addPbxGroup(['file.m'], 'MyGroup', 'Application'); + pbxGroupInPbx = proj.pbxGroupByName('MyGroup'); + + test.equal(pbxGroupInPbx.sourceTree, '""'); + test.done(); + }, + 'should add each of the files to PBXBuildFile section': function (test) { + var buildFileSection = proj.pbxBuildFileSection(); + for (var key in buildFileSection) { + test.notEqual(buildFileSection[key].fileRef_comment, 'file.m'); + test.notEqual(buildFileSection[key].fileRef_comment, 'assets.bundle'); + } + + var initialBuildFileSectionItemsCount = Object.keys(buildFileSection), + pbxGroup = proj.addPbxGroup(['file.m', 'assets.bundle'], 'MyGroup', 'Application', '""'), + afterAdditionBuildFileSectionItemsCount = Object.keys(buildFileSection); + + // for each file added in the build file section two keyes are added - one for the object and one for the comment + test.equal(initialBuildFileSectionItemsCount.length, afterAdditionBuildFileSectionItemsCount.length - 4); + test.done(); + }, + 'should not add any of the files to PBXBuildFile section if already added': function (test) { + var buildFileSection = proj.pbxBuildFileSection(), + initialBuildFileSectionItemsCount = Object.keys(buildFileSection), + pbxGroup = proj.addPbxGroup(['AppDelegate.m', 'AppDelegate.h'], 'MyGroup', 'Application', '""'), + afterAdditionBuildFileSectionItemsCount = Object.keys(buildFileSection); + + test.deepEqual(initialBuildFileSectionItemsCount, afterAdditionBuildFileSectionItemsCount); + test.done(); + }, + 'should not add any of the files to PBXBuildFile section when they contain special symbols and are already added': function (test) { + var buildFileSection = proj.pbxBuildFileSection(), + initialBuildFileSectionItemsCount = Object.keys(buildFileSection), + pbxGroup = proj.addPbxGroup(['KitchenSinktablet.app'], 'MyGroup', 'Application', '""'), + afterAdditionBuildFileSectionItemsCount = Object.keys(buildFileSection); + + test.deepEqual(initialBuildFileSectionItemsCount, afterAdditionBuildFileSectionItemsCount); + test.done(); + }, + 'should add all files which are not added and not add files already added to PBXBuildFile section': function (test) { + var buildFileSection = proj.pbxBuildFileSection(); + for (var key in buildFileSection) { + test.notEqual(buildFileSection[key].fileRef_comment, 'file.m'); + test.notEqual(buildFileSection[key].fileRef_comment, 'assets.bundle'); + } + + var initialBuildFileSectionItemsCount = Object.keys(buildFileSection), + pbxGroup = proj.addPbxGroup(['AppDelegate.m', 'AppDelegate.h', 'file.m', 'assets.bundle'], 'MyGroup', 'Application', '""'), + afterAdditionBuildFileSectionItemsCount = Object.keys(buildFileSection); + + // for each file added in the build file section two keyes are added - one for the object and one for the comment + test.equal(initialBuildFileSectionItemsCount.length, afterAdditionBuildFileSectionItemsCount.length - 4); + test.done(); + }, + 'should add each of the files to PBXFileReference section': function (test) { + var fileReference = proj.pbxFileReferenceSection(); + for (var key in fileReference) { + test.notEqual(fileReference[key].fileRef_comment, 'file.m'); + test.notEqual(fileReference[key].fileRef_comment, 'assets.bundle'); + } + var pbxGroup = proj.addPbxGroup(['file.m', 'assets.bundle'], 'MyGroup', 'Application', '""'); + for (var index = 0; index < pbxGroup.pbxGroup.children.length; index++) { + var file = pbxGroup.pbxGroup.children[index]; + test.ok(fileReference[file.value]); + } + + test.done(); + }, + 'should not add any of the files to PBXFileReference section if already added': function (test) { + var fileReference = proj.pbxFileReferenceSection (), + initialBuildFileSectionItemsCount = Object.keys(fileReference), + pbxGroup = proj.addPbxGroup(['AppDelegate.m', 'AppDelegate.h'], 'MyGroup', 'Application', '""'), + afterAdditionBuildFileSectionItemsCount = Object.keys(fileReference); + + test.deepEqual(initialBuildFileSectionItemsCount, afterAdditionBuildFileSectionItemsCount); + test.done(); + }, + 'should not add any of the files to PBXFileReference section when they contain special symbols and are already added': function (test) { + var fileReference = proj.pbxFileReferenceSection (), + initialBuildFileSectionItemsCount = Object.keys(fileReference), + pbxGroup = proj.addPbxGroup(['KitchenSinktablet.app'], 'MyGroup', 'Application', '""'), + afterAdditionBuildFileSectionItemsCount = Object.keys(fileReference); + + test.deepEqual(initialBuildFileSectionItemsCount, afterAdditionBuildFileSectionItemsCount); + test.done(); + }, + 'should add all files which are not added and not add files already added to PBXFileReference section': function (test) { + var fileReference = proj.pbxFileReferenceSection (); + for (var key in fileReference) { + test.notEqual(fileReference[key].fileRef_comment, 'file.m'); + test.notEqual(fileReference[key].fileRef_comment, 'assets.bundle'); + } + + var initialBuildFileSectionItemsCount = Object.keys(fileReference), + pbxGroup = proj.addPbxGroup(['AppDelegate.m', 'AppDelegate.h', 'file.m', 'assets.bundle'], 'MyGroup', 'Application', '""'), + afterAdditionBuildFileSectionItemsCount = Object.keys(fileReference); + + // for each file added in the file reference section two keyes are added - one for the object and one for the comment + test.equal(initialBuildFileSectionItemsCount.length, afterAdditionBuildFileSectionItemsCount.length - 4); + test.done(); + }, + 'should remove a pbxGroup': function (test) { + var groupName = 'MyGroup'; + proj.addPbxGroup(['file.m'], groupName, 'Application', 'Application', '""'); + 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 4caa22b..3959efb 100644 --- a/test/addResourceFile.js +++ b/test/addResourceFile.js @@ -90,7 +90,7 @@ exports.addResourceFile = { test.equal(fileRefEntry.isa, 'PBXFileReference'); test.equal(fileRefEntry.fileEncoding, undefined); - test.equal(fileRefEntry.lastKnownFileType, '"wrapper.plug-in"'); + test.equal(fileRefEntry.lastKnownFileType, 'wrapper.plug-in'); test.equal(fileRefEntry.name, '"assets.bundle"'); test.equal(fileRefEntry.path, '"Resources/assets.bundle"'); test.equal(fileRefEntry.sourceTree, '""'); @@ -151,7 +151,7 @@ exports.addResourceFile = { test.equal(fileRefEntry.isa, 'PBXFileReference'); test.equal(fileRefEntry.fileEncoding, undefined); - test.equal(fileRefEntry.lastKnownFileType, '"wrapper.plug-in"'); + test.equal(fileRefEntry.lastKnownFileType, 'wrapper.plug-in'); test.equal(fileRefEntry.name, '"assets.bundle"'); test.equal(fileRefEntry.path, '"Plugins/assets.bundle"'); test.equal(fileRefEntry.sourceTree, '""'); @@ -210,6 +210,22 @@ exports.addResourceFile = { test.done(); } }, + 'when added with { variantGroup: true }': { + + 'should not add to the PBXResourcesBuildPhase and PBXBuildFile': function (test) { + var newFile = proj.addResourceFile('en.lproj/Localization.strings', + { variantGroup: true }); + + var sources = proj.pbxResourcesBuildPhaseObj(); + test.equal(sources.files.length, 12); + + var buildFileSection = proj.pbxBuildFileSection(); + test.ok(buildFileSection[newFile.uuid] === undefined); + + test.done(); + }, + + }, 'duplicate entries': { 'should return false': function (test) { var newFile = proj.addResourceFile('Plugins/assets.bundle'); diff --git a/test/addTarget.js b/test/addTarget.js new file mode 100644 index 0000000..265bb0d --- /dev/null +++ b/test/addTarget.js @@ -0,0 +1,89 @@ +var fullProject = require('./fixtures/full-project') + fullProjectStr = JSON.stringify(fullProject), + pbx = require('../lib/pbxProject'), + proj = new pbx('.'); + +function cleanHash() { + return JSON.parse(fullProjectStr); +} + +var TARGET_NAME = 'TestExtension', + TARGET_TYPE = 'app_extension', + TARGET_SUBFOLDER_NAME = 'TestExtensionFiles'; + +exports.setUp = function (callback) { + proj.hash = cleanHash(); + callback(); +} + +exports.addTarget = { + 'should throw when target name is missing': function (test) { + test.throws(function() { + proj.addTarget(null, TARGET_TYPE); + }); + + test.done(); + }, + 'should throw when target type missing': function (test) { + test.throws(function() { + proj.addTarget(TARGET_NAME, null); + }); + + test.done(); + }, + 'should create a new target': function (test) { + var target = proj.addTarget(TARGET_NAME, TARGET_TYPE, TARGET_SUBFOLDER_NAME); + + test.ok(typeof target == 'object'); + test.ok(target.uuid); + test.ok(target.pbxNativeTarget); + test.ok(target.pbxNativeTarget.isa); + test.ok(target.pbxNativeTarget.name); + test.ok(target.pbxNativeTarget.productName); + test.ok(target.pbxNativeTarget.productReference); + test.ok(target.pbxNativeTarget.productType); + test.ok(target.pbxNativeTarget.buildConfigurationList); + test.ok(target.pbxNativeTarget.buildPhases); + test.ok(target.pbxNativeTarget.buildRules); + test.ok(target.pbxNativeTarget.dependencies); + + test.done(); + }, + 'should create a new target and add source, framework, resource and header files and the corresponding build phases': function (test) { + var target = proj.addTarget(TARGET_NAME, TARGET_TYPE, TARGET_SUBFOLDER_NAME), + options = { 'target' : target.uuid }; + + var sourceFile = proj.addSourceFile('Plugins/file.m', options), + sourcePhase = proj.addBuildPhase([], 'PBXSourcesBuildPhase', 'Sources', target.uuid), + resourceFile = proj.addResourceFile('assets.bundle', options), + resourcePhase = proj.addBuildPhase([], 'PBXResourcesBuildPhase', 'Resources', target.uuid), + frameworkFile = proj.addFramework('libsqlite3.dylib', options); + frameworkPhase = proj.addBuildPhase([], 'PBXFrameworkBuildPhase', 'Frameworks', target.uuid), + headerFile = proj.addHeaderFile('file.h', options); + + test.ok(sourcePhase); + test.ok(resourcePhase); + test.ok(frameworkPhase); + + test.equal(sourceFile.constructor, pbxFile); + test.equal(resourceFile.constructor, pbxFile); + test.equal(frameworkFile.constructor, pbxFile); + test.equal(headerFile.constructor, pbxFile); + + test.ok(typeof target == 'object'); + test.ok(target.uuid); + test.ok(target.pbxNativeTarget); + test.ok(target.pbxNativeTarget.isa); + test.ok(target.pbxNativeTarget.name); + test.ok(target.pbxNativeTarget.productName); + test.ok(target.pbxNativeTarget.productReference); + test.ok(target.pbxNativeTarget.productType); + test.ok(target.pbxNativeTarget.buildConfigurationList); + test.ok(target.pbxNativeTarget.buildPhases); + test.ok(target.pbxNativeTarget.buildRules); + test.ok(target.pbxNativeTarget.dependencies); + + test.done(); + + } +} diff --git a/test/addTargetDependency.js b/test/addTargetDependency.js new file mode 100644 index 0000000..2ed6983 --- /dev/null +++ b/test/addTargetDependency.js @@ -0,0 +1,146 @@ +var fullProject = require('./fixtures/full-project') + fullProjectStr = JSON.stringify(fullProject), + pbx = require('../lib/pbxProject'), + proj = new pbx('.'); + +function cleanHash() { + return JSON.parse(fullProjectStr); +} + +exports.setUp = function (callback) { + proj.hash = cleanHash(); + callback(); +} + +exports.addTargetDependency = { + 'should return undefined when no target specified': function (test) { + var buildPhase = proj.addTargetDependency(); + + test.ok(typeof buildPhase === 'undefined'); + test.done() + }, + 'should throw when target not found in nativeTargetsSection': function (test) { + test.throws(function() { + proj.addTargetDependency('invalidTarget'); + }); + test.done() + }, + 'should throw when any dependency target not found in nativeTargetsSection': function (test) { + test.throws(function() { + proj.addTargetDependency('1D6058900D05DD3D006BFB54', ['invalidTarget']); + }); + test.done() + }, + 'should return the pbxTarget': function (test) { + var target = proj.addTargetDependency('1D6058900D05DD3D006BFB54', ['1D6058900D05DD3D006BFB54']); + + test.ok(typeof target == 'object'); + test.ok(target.uuid); + test.ok(target.target); + test.done(); + }, + 'should add targetDependencies to target': function (test) { + var targetInPbxProj = proj.pbxNativeTargetSection()['1D6058900D05DD3D006BFB55']; + test.deepEqual(targetInPbxProj.dependencies, []); + + var target = proj.addTargetDependency('1D6058900D05DD3D006BFB55', ['1D6058900D05DD3D006BFB54', '1D6058900D05DD3D006BFB55']).target; + test.deepEqual(targetInPbxProj.dependencies, target.dependencies) + test.done() + }, + 'should create a PBXTargetDependency for each dependency target': function (test) { + var pbxTargetDependencySection = proj.hash.project.objects['PBXTargetDependency'], + target = proj.addTargetDependency('1D6058900D05DD3D006BFB54', ['1D6058900D05DD3D006BFB54', '1D6058900D05DD3D006BFB55']).target; + + for (var index = 0; index < target.dependencies.length; index++) { + var dependency = target.dependencies[index].value; + test.ok(pbxTargetDependencySection[dependency]); + } + + test.done() + }, + 'should set right comment for each dependency target': function (test) { + var pbxTargetDependencySection = proj.hash.project.objects['PBXTargetDependency'], + target = proj.addTargetDependency('1D6058900D05DD3D006BFB54', ['1D6058900D05DD3D006BFB54', '1D6058900D05DD3D006BFB55']).target; + + for (var index = 0; index < target.dependencies.length; index++) { + var dependencyCommentKey = target.dependencies[index].value + '_comment'; + test.equal(pbxTargetDependencySection[dependencyCommentKey], 'PBXTargetDependency'); + } + + test.done() + }, + 'should create a PBXContainerItemProxy for each PBXTargetDependency': function (test) { + var pbxTargetDependencySection = proj.hash.project.objects['PBXTargetDependency'], + pbxContainerItemProxySection = proj.hash.project.objects['PBXContainerItemProxy'], + target = proj.addTargetDependency('1D6058900D05DD3D006BFB54', ['1D6058900D05DD3D006BFB54', '1D6058900D05DD3D006BFB55']).target; + + for (var index = 0; index < target.dependencies.length; index++) { + var dependency = target.dependencies[index].value, + targetProxy = pbxTargetDependencySection[dependency]['targetProxy']; + + test.ok(pbxContainerItemProxySection[targetProxy]); + } + + test.done() + }, + 'should set each PBXContainerItemProxy`s remoteGlobalIDString correctly': function (test) { + var pbxTargetDependencySection = proj.hash.project.objects['PBXTargetDependency'], + pbxContainerItemProxySection = proj.hash.project.objects['PBXContainerItemProxy'], + target = proj.addTargetDependency('1D6058900D05DD3D006BFB55', ['1D6058900D05DD3D006BFB54', '1D6058900D05DD3D006BFB55']).target, + remoteGlobalIDStrings = []; + + for (var index = 0; index < target.dependencies.length; index++) { + var dependency = target.dependencies[index].value, + targetProxy = pbxTargetDependencySection[dependency]['targetProxy']; + + remoteGlobalIDStrings.push(pbxContainerItemProxySection[targetProxy]['remoteGlobalIDString']); + } + + test.deepEqual(remoteGlobalIDStrings, ['1D6058900D05DD3D006BFB54', '1D6058900D05DD3D006BFB55']); + test.done() + }, + 'should set each PBXContainerItemProxy`s remoteInfo correctly': function (test) { + var pbxTargetDependencySection = proj.hash.project.objects['PBXTargetDependency'], + pbxContainerItemProxySection = proj.hash.project.objects['PBXContainerItemProxy'], + target = proj.addTargetDependency('1D6058900D05DD3D006BFB55', ['1D6058900D05DD3D006BFB54', '1D6058900D05DD3D006BFB55']).target, + remoteInfoArray = []; + + for (var index = 0; index < target.dependencies.length; index++) { + var dependency = target.dependencies[index].value, + targetProxy = pbxTargetDependencySection[dependency]['targetProxy']; + + remoteInfoArray.push(pbxContainerItemProxySection[targetProxy]['remoteInfo']); + } + + test.deepEqual(remoteInfoArray, ['"KitchenSinktablet"', '"TestApp"']); + test.done() + }, + 'should set each PBXContainerItemProxy`s containerPortal correctly': function (test) { + var pbxTargetDependencySection = proj.hash.project.objects['PBXTargetDependency'], + pbxContainerItemProxySection = proj.hash.project.objects['PBXContainerItemProxy'], + target = proj.addTargetDependency('1D6058900D05DD3D006BFB55', ['1D6058900D05DD3D006BFB54', '1D6058900D05DD3D006BFB55']).target; + + for (var index = 0; index < target.dependencies.length; index++) { + var dependency = target.dependencies[index].value, + targetProxy = pbxTargetDependencySection[dependency]['targetProxy']; + + test.equal(pbxContainerItemProxySection[targetProxy]['containerPortal'], proj.hash.project['rootObject']); + } + + test.done() + }, + 'should set each PBXContainerItemProxy`s proxyType correctly': function (test) { + var pbxTargetDependencySection = proj.hash.project.objects['PBXTargetDependency'], + pbxContainerItemProxySection = proj.hash.project.objects['PBXContainerItemProxy'], + target = proj.addTargetDependency('1D6058900D05DD3D006BFB55', ['1D6058900D05DD3D006BFB54', '1D6058900D05DD3D006BFB55']).target; + + for (var index = 0; index < target.dependencies.length; index++) { + var dependency = target.dependencies[index].value, + targetProxy = pbxTargetDependencySection[dependency]['targetProxy']; + + test.equal(pbxContainerItemProxySection[targetProxy]['proxyType'], 1); + } + + test.done() + } +} diff --git a/test/addToPbxFileReferenceSection.js b/test/addToPbxFileReferenceSection.js new file mode 100644 index 0000000..a3319a7 --- /dev/null +++ b/test/addToPbxFileReferenceSection.js @@ -0,0 +1,62 @@ +var jsonProject = require('./fixtures/full-project') + fullProjectStr = JSON.stringify(jsonProject), + pbx = require('../lib/pbxProject'), + pbxFile = require('../lib/pbxFile'), + myProj = new pbx('.'); + +function cleanHash() { + return JSON.parse(fullProjectStr); +} + +exports.setUp = function (callback) { + myProj.hash = cleanHash(); + callback(); +} + +exports['addToPbxFileReferenceSection function'] = { + 'should add file and comment to fileReferenceSection': function (test) { + var file = new pbxFile('file.m'); + file.fileRef = myProj.generateUuid(); + + myProj.addToPbxFileReferenceSection(file) + + 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].sourceTree, '""'); + test.equal(myProj.pbxFileReferenceSection()[file.fileRef].fileEncoding, 4); + test.equal(myProj.pbxFileReferenceSection()[file.fileRef + "_comment"], 'file.m'); + test.done(); + }, + 'should add file with preset explicitFileType to fileReferenceSection correctly': function (test) { + var appexFile = { fileRef: myProj.generateUuid(), isa: 'PBXFileReference', explicitFileType: '"wrapper.app-extension"', path: "WatchKit Extension.appex"}; + + myProj.addToPbxFileReferenceSection(appexFile) + + test.equal(myProj.pbxFileReferenceSection()[appexFile.fileRef].isa, 'PBXFileReference'); + test.equal(myProj.pbxFileReferenceSection()[appexFile.fileRef].explicitFileType, '"wrapper.app-extension"'); + test.equal(myProj.pbxFileReferenceSection()[appexFile.fileRef].path, '"WatchKit Extension.appex"'); + test.done(); + }, + 'should add file with preset includeInIndex to fileReferenceSection correctly': function (test) { + var appexFile = { fileRef: myProj.generateUuid(), isa: 'PBXFileReference', includeInIndex: 0, path: "WatchKit Extension.appex"}; + + myProj.addToPbxFileReferenceSection(appexFile) + + test.equal(myProj.pbxFileReferenceSection()[appexFile.fileRef].isa, 'PBXFileReference'); + test.equal(myProj.pbxFileReferenceSection()[appexFile.fileRef].includeInIndex, 0); + test.equal(myProj.pbxFileReferenceSection()[appexFile.fileRef].path, '"WatchKit Extension.appex"'); + test.done(); + }, + 'should add file with preset sourceTree to fileReferenceSection correctly': function (test) { + var appexFile = { fileRef: myProj.generateUuid(), isa: 'PBXFileReference', sourceTree: 'BUILT_PRODUCTS_DIR', path: "WatchKit Extension.appex"}; + + myProj.addToPbxFileReferenceSection(appexFile) + + test.equal(myProj.pbxFileReferenceSection()[appexFile.fileRef].isa, 'PBXFileReference'); + test.equal(myProj.pbxFileReferenceSection()[appexFile.fileRef].sourceTree, 'BUILT_PRODUCTS_DIR'); + test.equal(myProj.pbxFileReferenceSection()[appexFile.fileRef].path, '"WatchKit Extension.appex"'); + test.done(); + } +} \ No newline at end of file diff --git a/test/addXCConfigurationList.js b/test/addXCConfigurationList.js new file mode 100644 index 0000000..9ebe2a2 --- /dev/null +++ b/test/addXCConfigurationList.js @@ -0,0 +1,115 @@ +var fullProject = require('./fixtures/full-project') + fullProjectStr = JSON.stringify(fullProject), + pbx = require('../lib/pbxProject'), + proj = new pbx('.'), + debugConfiguration = { + isa: 'XCBuildConfiguration', + buildSettings: { + GCC_PREPROCESSOR_DEFINITIONS: [ + '"DEBUG=1"', + '"$(inherited)"', + ], + INFOPLIST_FILE: "Info.Plist", + LD_RUNPATH_SEARCH_PATHS: '"$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"', + PRODUCT_NAME: '"${TARGET_NAME}"', + SKIP_INSTALL: 'YES' + }, + name: 'Debug' + }, + releaseConfiguration = { + isa: 'XCBuildConfiguration', + buildSettings: { + INFOPLIST_FILE: "Info.Plist", + LD_RUNPATH_SEARCH_PATHS: '"$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"', + PRODUCT_NAME: '"${TARGET_NAME}"', + SKIP_INSTALL: 'YES' + }, + name: 'Release' + }; + +function cleanHash() { + return JSON.parse(fullProjectStr); +} + +exports.setUp = function (callback) { + proj.hash = cleanHash(); + callback(); +} + +exports.addXCConfigurationList = { + 'should return an XCConfigurationList': function (test) { + var myProj = new pbx('test/parser/projects/full.pbxproj').parseSync(), + xcConfigurationList = myProj.addXCConfigurationList([debugConfiguration, releaseConfiguration], 'Release', 'XCConfigurationList Comment'); + + test.ok(typeof xcConfigurationList === 'object'); + test.done(); + }, + 'should set a uuid on the XCConfigurationList': function (test) { + var myProj = new pbx('test/parser/projects/full.pbxproj').parseSync(), + xcConfigurationList = myProj.addXCConfigurationList([debugConfiguration, releaseConfiguration], 'Release', 'XCConfigurationList Comment'); + + test.ok(xcConfigurationList.uuid); + test.done(); + }, + 'should add configurations to pbxBuildConfigurationSection': function (test) { + var myProj = new pbx('test/parser/projects/full.pbxproj').parseSync(), + pbxBuildConfigurationSection = myProj.pbxXCBuildConfigurationSection(), + xcConfigurationList = myProj.addXCConfigurationList([debugConfiguration, releaseConfiguration], 'Release', 'XCConfigurationList Comment'), + xcConfigurationListConfigurations = xcConfigurationList.xcConfigurationList.buildConfigurations; + + for (var index = 0; index < xcConfigurationListConfigurations.length; index++) { + var configuration = xcConfigurationListConfigurations[index]; + test.ok(pbxBuildConfigurationSection[configuration.value]); + } + + test.done(); + }, + 'should add XCConfigurationList to pbxXCConfigurationListSection': function (test) { + var myProj = new pbx('test/parser/projects/full.pbxproj').parseSync(), + pbxXCConfigurationListSection = myProj.pbxXCConfigurationList(); + xcConfigurationList = myProj.addXCConfigurationList([debugConfiguration, releaseConfiguration], 'Release', 'XCConfigurationList Comment'); + + test.ok(pbxXCConfigurationListSection[xcConfigurationList.uuid]); + test.done(); + }, + 'should add XCConfigurationList object correctly': function (test) { + var myProj = new pbx('test/parser/projects/full.pbxproj').parseSync(), + pbxXCConfigurationListSection = myProj.pbxXCConfigurationList(); + xcConfigurationList = myProj.addXCConfigurationList([debugConfiguration, releaseConfiguration], 'Release', 'XCConfigurationList Comment'), + xcConfigurationListInPbx = pbxXCConfigurationListSection[xcConfigurationList.uuid]; + + test.deepEqual(xcConfigurationListInPbx, xcConfigurationList.xcConfigurationList); + test.done(); + }, + 'should add correct configurations to XCConfigurationList and to pbxBuildConfigurationSection': function (test) { + var myProj = new pbx('test/parser/projects/full.pbxproj').parseSync(), + pbxXCConfigurationListSection = myProj.pbxXCConfigurationList(); + pbxBuildConfigurationSection = myProj.pbxXCBuildConfigurationSection(), + xcConfigurationList = myProj.addXCConfigurationList([debugConfiguration, releaseConfiguration], 'Release', 'XCConfigurationList Comment'), + xcConfigurationListConfigurations = xcConfigurationList.xcConfigurationList.buildConfigurations, + expectedConfigurations = [], + xcConfigurationListInPbx = pbxXCConfigurationListSection[xcConfigurationList.uuid]; + + for (var index = 0; index < xcConfigurationListConfigurations.length; index++) { + var configuration = xcConfigurationListConfigurations[index]; + expectedConfigurations.push(pbxBuildConfigurationSection[configuration.value]); + } + + test.deepEqual(expectedConfigurations, [debugConfiguration, releaseConfiguration]); + test.deepEqual(xcConfigurationListInPbx.buildConfigurations, xcConfigurationListConfigurations); + test.done(); + }, + 'should set comments for pbxBuildConfigurations': function (test) { + var myProj = new pbx('test/parser/projects/full.pbxproj').parseSync(), + pbxBuildConfigurationSection = myProj.pbxXCBuildConfigurationSection(), + xcConfigurationList = myProj.addXCConfigurationList([debugConfiguration, releaseConfiguration], 'Release', 'XCConfigurationList Comment'), + xcConfigurationListConfigurations = xcConfigurationList.xcConfigurationList.buildConfigurations; + + for (var index = 0; index < xcConfigurationListConfigurations.length; index++) { + var configuration = xcConfigurationListConfigurations[index]; + test.ok(pbxBuildConfigurationSection[configuration.value + '_comment']); + } + + test.done(); + } +} diff --git a/test/dataModelDocument.js b/test/dataModelDocument.js new file mode 100644 index 0000000..fa0b8a8 --- /dev/null +++ b/test/dataModelDocument.js @@ -0,0 +1,162 @@ +var jsonProject = require('./fixtures/full-project') + fullProjectStr = JSON.stringify(jsonProject), + path = require('path'), + pbx = require('../lib/pbxProject'), + pbxFile = require('../lib/pbxFile'), + proj = new pbx('.'), + singleDataModelFilePath = __dirname + '/fixtures/single-data-model.xcdatamodeld', + multipleDataModelFilePath = __dirname + '/fixtures/multiple-data-model.xcdatamodeld'; + +function cleanHash() { + return JSON.parse(fullProjectStr); +} + +exports.setUp = function (callback) { + proj.hash = cleanHash(); + callback(); +} + +exports.dataModelDocument = { + 'should return a pbxFile': function (test) { + var newFile = proj.addDataModelDocument(singleDataModelFilePath); + + test.equal(newFile.constructor, pbxFile); + test.done() + }, + 'should set a uuid on the pbxFile': function (test) { + var newFile = proj.addDataModelDocument(singleDataModelFilePath); + + test.ok(newFile.uuid); + test.done() + }, + 'should set a fileRef on the pbxFile': function (test) { + var newFile = proj.addDataModelDocument(singleDataModelFilePath); + + test.ok(newFile.fileRef); + test.done() + }, + 'should set an optional target on the pbxFile': function (test) { + var newFile = proj.addDataModelDocument(singleDataModelFilePath, undefined, { target: target }), + target = proj.findTargetKey('TestApp'); + + test.equal(newFile.target, target); + test.done() + }, + 'should populate the PBXBuildFile section with 2 fields': function (test) { + var newFile = proj.addDataModelDocument(singleDataModelFilePath), + buildFileSection = proj.pbxBuildFileSection(), + bfsLength = Object.keys(buildFileSection).length; + + test.equal(59 + 1, bfsLength); + test.ok(buildFileSection[newFile.uuid]); + test.ok(buildFileSection[newFile.uuid + '_comment']); + + test.done(); + }, + 'should populate the PBXFileReference section with 2 fields for single model document': function (test) { + var newFile = proj.addDataModelDocument(singleDataModelFilePath), + fileRefSection = proj.pbxFileReferenceSection(), + frsLength = Object.keys(fileRefSection).length; + + test.equal(66 + 2, frsLength); + test.ok(fileRefSection[newFile.models[0].fileRef]); + test.ok(fileRefSection[newFile.models[0].fileRef + '_comment']); + + test.done(); + }, + 'should populate the PBXFileReference section with 2 fields for each model of a model document': function (test) { + var newFile = proj.addDataModelDocument(multipleDataModelFilePath), + fileRefSection = proj.pbxFileReferenceSection(), + frsLength = Object.keys(fileRefSection).length; + + test.equal(66 + 2 * 2, frsLength); + test.ok(fileRefSection[newFile.models[0].fileRef]); + test.ok(fileRefSection[newFile.models[0].fileRef + '_comment']); + test.ok(fileRefSection[newFile.models[1].fileRef]); + test.ok(fileRefSection[newFile.models[1].fileRef + '_comment']); + + test.done(); + }, + 'should add to resources group by default': function (test) { + var newFile = proj.addDataModelDocument(singleDataModelFilePath); + groupChildren = proj.pbxGroupByName('Resources').children, + found = false; + + for (var index in groupChildren) { + if (groupChildren[index].comment === 'single-data-model.xcdatamodeld') { + found = true; + break; + } + } + test.ok(found); + test.done(); + }, + 'should add to group specified by key': function (test) { + var group = 'Frameworks', + newFile = proj.addDataModelDocument(singleDataModelFilePath, proj.findPBXGroupKey({ name: group })); + groupChildren = proj.pbxGroupByName(group).children; + + var found = false; + for (var index in groupChildren) { + if (groupChildren[index].comment === path.basename(singleDataModelFilePath)) { + found = true; + break; + } + } + test.ok(found); + test.done(); + }, + 'should add to group specified by name': function (test) { + var group = 'Frameworks', + newFile = proj.addDataModelDocument(singleDataModelFilePath, group); + groupChildren = proj.pbxGroupByName(group).children; + + var found = false; + for (var index in groupChildren) { + if (groupChildren[index].comment === path.basename(singleDataModelFilePath)) { + found = true; + break; + } + } + test.ok(found); + test.done(); + }, + 'should add to the PBXSourcesBuildPhase': function (test) { + var newFile = proj.addDataModelDocument(singleDataModelFilePath), + sources = proj.pbxSourcesBuildPhaseObj(); + + test.equal(sources.files.length, 2 + 1); + test.done(); + }, + 'should create a XCVersionGroup section': function (test) { + var newFile = proj.addDataModelDocument(singleDataModelFilePath), + xcVersionGroupSection = proj.xcVersionGroupSection(); + + test.ok(xcVersionGroupSection[newFile.fileRef]); + test.done(); + }, + 'should populate the XCVersionGroup comment correctly': function (test) { + var newFile = proj.addDataModelDocument(singleDataModelFilePath), + xcVersionGroupSection = proj.xcVersionGroupSection(), + commentKey = newFile.fileRef + '_comment'; + + test.equal(xcVersionGroupSection[commentKey], path.basename(singleDataModelFilePath)); + test.done(); + }, + 'should add the XCVersionGroup object correctly': function (test) { + var newFile = proj.addDataModelDocument(singleDataModelFilePath), + xcVersionGroupSection = proj.xcVersionGroupSection(), + xcVersionGroupEntry = xcVersionGroupSection[newFile.fileRef]; + + test.equal(xcVersionGroupEntry.isa, 'XCVersionGroup'); + test.equal(xcVersionGroupEntry.children[0], newFile.models[0].fileRef); + test.equal(xcVersionGroupEntry.currentVersion, newFile.currentModel.fileRef); + test.equal(xcVersionGroupEntry.name, path.basename(singleDataModelFilePath)); + // Need to validate against normalized path, since paths should contain forward slash on OSX + test.equal(xcVersionGroupEntry.path, singleDataModelFilePath.replace(/\\/g, '/')); + test.equal(xcVersionGroupEntry.sourceTree, '""'); + test.equal(xcVersionGroupEntry.versionGroupType, 'wrapper.xcdatamodel'); + + test.done(); + } +} diff --git a/test/fixtures/full-project.json b/test/fixtures/full-project.json index a66b359..09ec88e 100644 --- a/test/fixtures/full-project.json +++ b/test/fixtures/full-project.json @@ -1 +1,1252 @@ -{"project":{"archiveVersion":1,"classes":{},"objectVersion":45,"objects":{"PBXBuildFile":{"1D3623260D0F684500981E51":{"isa":"PBXBuildFile","fileRef":"1D3623250D0F684500981E51","fileRef_comment":"AppDelegate.m"},"1D3623260D0F684500981E51_comment":"AppDelegate.m in Sources","1D60589B0D05DD56006BFB54":{"isa":"PBXBuildFile","fileRef":"29B97316FDCFA39411CA2CEA","fileRef_comment":"main.m"},"1D60589B0D05DD56006BFB54_comment":"main.m in Sources","1D60589F0D05DD5A006BFB54":{"isa":"PBXBuildFile","fileRef":"1D30AB110D05D00D00671497","fileRef_comment":"Foundation.framework"},"1D60589F0D05DD5A006BFB54_comment":"Foundation.framework in Frameworks","1DF5F4E00D08C38300B7A737":{"isa":"PBXBuildFile","fileRef":"1DF5F4DF0D08C38300B7A737","fileRef_comment":"UIKit.framework","settings":{"ATTRIBUTES":["Weak"]}},"1DF5F4E00D08C38300B7A737_comment":"UIKit.framework in Frameworks","1F766FE113BBADB100FB74C0":{"isa":"PBXBuildFile","fileRef":"1F766FDC13BBADB100FB74C0","fileRef_comment":"Localizable.strings"},"1F766FE113BBADB100FB74C0_comment":"Localizable.strings in Resources","1F766FE213BBADB100FB74C0":{"isa":"PBXBuildFile","fileRef":"1F766FDF13BBADB100FB74C0","fileRef_comment":"Localizable.strings"},"1F766FE213BBADB100FB74C0_comment":"Localizable.strings in Resources","288765FD0DF74451002DB57D":{"isa":"PBXBuildFile","fileRef":"288765FC0DF74451002DB57D","fileRef_comment":"CoreGraphics.framework"},"288765FD0DF74451002DB57D_comment":"CoreGraphics.framework in Frameworks","301BF552109A68D80062928A":{"isa":"PBXBuildFile","fileRef":"301BF535109A57CC0062928A","fileRef_comment":"libPhoneGap.a"},"301BF552109A68D80062928A_comment":"libPhoneGap.a in Frameworks","301BF570109A69640062928A":{"isa":"PBXBuildFile","fileRef":"301BF56E109A69640062928A","fileRef_comment":"www"},"301BF570109A69640062928A_comment":"www in Resources","301BF5B5109A6A2B0062928A":{"isa":"PBXBuildFile","fileRef":"301BF5B4109A6A2B0062928A","fileRef_comment":"AddressBook.framework"},"301BF5B5109A6A2B0062928A_comment":"AddressBook.framework in Frameworks","301BF5B7109A6A2B0062928A":{"isa":"PBXBuildFile","fileRef":"301BF5B6109A6A2B0062928A","fileRef_comment":"AddressBookUI.framework"},"301BF5B7109A6A2B0062928A_comment":"AddressBookUI.framework in Frameworks","301BF5B9109A6A2B0062928A":{"isa":"PBXBuildFile","fileRef":"301BF5B8109A6A2B0062928A","fileRef_comment":"AudioToolbox.framework"},"301BF5B9109A6A2B0062928A_comment":"AudioToolbox.framework in Frameworks","301BF5BB109A6A2B0062928A":{"isa":"PBXBuildFile","fileRef":"301BF5BA109A6A2B0062928A","fileRef_comment":"AVFoundation.framework","settings":{"ATTRIBUTES":["Weak"]}},"301BF5BB109A6A2B0062928A_comment":"AVFoundation.framework in Frameworks","301BF5BD109A6A2B0062928A":{"isa":"PBXBuildFile","fileRef":"301BF5BC109A6A2B0062928A","fileRef_comment":"CFNetwork.framework"},"301BF5BD109A6A2B0062928A_comment":"CFNetwork.framework in Frameworks","301BF5BF109A6A2B0062928A":{"isa":"PBXBuildFile","fileRef":"301BF5BE109A6A2B0062928A","fileRef_comment":"CoreLocation.framework"},"301BF5BF109A6A2B0062928A_comment":"CoreLocation.framework in Frameworks","301BF5C1109A6A2B0062928A":{"isa":"PBXBuildFile","fileRef":"301BF5C0109A6A2B0062928A","fileRef_comment":"MediaPlayer.framework"},"301BF5C1109A6A2B0062928A_comment":"MediaPlayer.framework in Frameworks","301BF5C3109A6A2B0062928A":{"isa":"PBXBuildFile","fileRef":"301BF5C2109A6A2B0062928A","fileRef_comment":"QuartzCore.framework"},"301BF5C3109A6A2B0062928A_comment":"QuartzCore.framework in Frameworks","301BF5C5109A6A2B0062928A":{"isa":"PBXBuildFile","fileRef":"301BF5C4109A6A2B0062928A","fileRef_comment":"SystemConfiguration.framework"},"301BF5C5109A6A2B0062928A_comment":"SystemConfiguration.framework in Frameworks","3053AC6F109B7857006FCFE7":{"isa":"PBXBuildFile","fileRef":"3053AC6E109B7857006FCFE7","fileRef_comment":"VERSION"},"3053AC6F109B7857006FCFE7_comment":"VERSION in Resources","305D5FD1115AB8F900A74A75":{"isa":"PBXBuildFile","fileRef":"305D5FD0115AB8F900A74A75","fileRef_comment":"MobileCoreServices.framework"},"305D5FD1115AB8F900A74A75_comment":"MobileCoreServices.framework in Frameworks","3072F99713A8081B00425683":{"isa":"PBXBuildFile","fileRef":"3072F99613A8081B00425683","fileRef_comment":"Capture.bundle"},"3072F99713A8081B00425683_comment":"Capture.bundle in Resources","307D28A2123043360040C0FA":{"isa":"PBXBuildFile","fileRef":"307D28A1123043350040C0FA","fileRef_comment":"PhoneGapBuildSettings.xcconfig"},"307D28A2123043360040C0FA_comment":"PhoneGapBuildSettings.xcconfig in Resources","308D05371370CCF300D202BF":{"isa":"PBXBuildFile","fileRef":"308D052E1370CCF300D202BF","fileRef_comment":"icon-72.png"},"308D05371370CCF300D202BF_comment":"icon-72.png in Resources","308D05381370CCF300D202BF":{"isa":"PBXBuildFile","fileRef":"308D052F1370CCF300D202BF","fileRef_comment":"icon.png"},"308D05381370CCF300D202BF_comment":"icon.png in Resources","308D05391370CCF300D202BF":{"isa":"PBXBuildFile","fileRef":"308D05301370CCF300D202BF","fileRef_comment":"icon@2x.png"},"308D05391370CCF300D202BF_comment":"icon@2x.png in Resources","308D053C1370CCF300D202BF":{"isa":"PBXBuildFile","fileRef":"308D05341370CCF300D202BF","fileRef_comment":"Default.png"},"308D053C1370CCF300D202BF_comment":"Default.png in Resources","308D053D1370CCF300D202BF":{"isa":"PBXBuildFile","fileRef":"308D05351370CCF300D202BF","fileRef_comment":"Default@2x.png"},"308D053D1370CCF300D202BF_comment":"Default@2x.png in Resources","30E1352710E2C1420031B30D":{"isa":"PBXBuildFile","fileRef":"30E1352610E2C1420031B30D","fileRef_comment":"PhoneGap.plist"},"30E1352710E2C1420031B30D_comment":"PhoneGap.plist in Resources","30E5649213A7FCAF007403D8":{"isa":"PBXBuildFile","fileRef":"30E5649113A7FCAF007403D8","fileRef_comment":"CoreMedia.framework","settings":{"ATTRIBUTES":["Weak"]}},"30E5649213A7FCAF007403D8_comment":"CoreMedia.framework in Frameworks"},"PBXContainerItemProxy":{"301BF534109A57CC0062928A":{"isa":"PBXContainerItemProxy","containerPortal":"301BF52D109A57CC0062928A","containerPortal_comment":"PhoneGapLib.xcodeproj","proxyType":2,"remoteGlobalIDString":"D2AAC07E0554694100DB518D","remoteInfo":"PhoneGapLib"},"301BF534109A57CC0062928A_comment":"PBXContainerItemProxy","301BF550109A68C00062928A":{"isa":"PBXContainerItemProxy","containerPortal":"301BF52D109A57CC0062928A","containerPortal_comment":"PhoneGapLib.xcodeproj","proxyType":1,"remoteGlobalIDString":"D2AAC07D0554694100DB518D","remoteInfo":"PhoneGapLib"},"301BF550109A68C00062928A_comment":"PBXContainerItemProxy","30E47BC2136F595F00DBB853":{"isa":"PBXContainerItemProxy","containerPortal":"301BF52D109A57CC0062928A","containerPortal_comment":"PhoneGapLib.xcodeproj","proxyType":2,"remoteGlobalIDString":"303258D8136B2C9400982B63","remoteInfo":"PhoneGap"},"30E47BC2136F595F00DBB853_comment":"PBXContainerItemProxy"},"PBXFileReference":{"1D30AB110D05D00D00671497":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"Foundation.framework","path":"System/Library/Frameworks/Foundation.framework","sourceTree":"SDKROOT"},"1D30AB110D05D00D00671497_comment":"Foundation.framework","1D3623240D0F684500981E51":{"isa":"PBXFileReference","fileEncoding":4,"lastKnownFileType":"sourcecode.c.h","path":"AppDelegate.h","sourceTree":"\"\""},"1D3623240D0F684500981E51_comment":"AppDelegate.h","1D3623250D0F684500981E51":{"isa":"PBXFileReference","fileEncoding":4,"lastKnownFileType":"sourcecode.c.objc","path":"AppDelegate.m","sourceTree":"\"\""},"1D3623250D0F684500981E51_comment":"AppDelegate.m","1D6058910D05DD3D006BFB54":{"isa":"PBXFileReference","explicitFileType":"wrapper.application","includeInIndex":0,"path":"\"KitchenSinktablet.app\"","sourceTree":"BUILT_PRODUCTS_DIR"},"1D6058910D05DD3D006BFB54_comment":"KitchenSinktablet.app","1DF5F4DF0D08C38300B7A737":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"UIKit.framework","path":"System/Library/Frameworks/UIKit.framework","sourceTree":"SDKROOT"},"1DF5F4DF0D08C38300B7A737_comment":"UIKit.framework","1F766FDD13BBADB100FB74C0":{"isa":"PBXFileReference","lastKnownFileType":"text.plist.strings","name":"en","path":"Localizable.strings","sourceTree":"\"\""},"1F766FDD13BBADB100FB74C0_comment":"en","1F766FE013BBADB100FB74C0":{"isa":"PBXFileReference","lastKnownFileType":"text.plist.strings","name":"es","path":"Localizable.strings","sourceTree":"\"\""},"1F766FE013BBADB100FB74C0_comment":"es","288765FC0DF74451002DB57D":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"CoreGraphics.framework","path":"System/Library/Frameworks/CoreGraphics.framework","sourceTree":"SDKROOT"},"288765FC0DF74451002DB57D_comment":"CoreGraphics.framework","29B97316FDCFA39411CA2CEA":{"isa":"PBXFileReference","fileEncoding":4,"lastKnownFileType":"sourcecode.c.objc","path":"main.m","sourceTree":"\"\""},"29B97316FDCFA39411CA2CEA_comment":"main.m","301BF52D109A57CC0062928A":{"isa":"PBXFileReference","lastKnownFileType":"\"wrapper.pb-project\"","path":"PhoneGapLib.xcodeproj","sourceTree":"PHONEGAPLIB"},"301BF52D109A57CC0062928A_comment":"PhoneGapLib.xcodeproj","301BF56E109A69640062928A":{"isa":"PBXFileReference","lastKnownFileType":"folder","path":"www","sourceTree":"SOURCE_ROOT"},"301BF56E109A69640062928A_comment":"www","301BF5B4109A6A2B0062928A":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"AddressBook.framework","path":"System/Library/Frameworks/AddressBook.framework","sourceTree":"SDKROOT"},"301BF5B4109A6A2B0062928A_comment":"AddressBook.framework","301BF5B6109A6A2B0062928A":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"AddressBookUI.framework","path":"System/Library/Frameworks/AddressBookUI.framework","sourceTree":"SDKROOT"},"301BF5B6109A6A2B0062928A_comment":"AddressBookUI.framework","301BF5B8109A6A2B0062928A":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"AudioToolbox.framework","path":"System/Library/Frameworks/AudioToolbox.framework","sourceTree":"SDKROOT"},"301BF5B8109A6A2B0062928A_comment":"AudioToolbox.framework","301BF5BA109A6A2B0062928A":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"AVFoundation.framework","path":"System/Library/Frameworks/AVFoundation.framework","sourceTree":"SDKROOT"},"301BF5BA109A6A2B0062928A_comment":"AVFoundation.framework","301BF5BC109A6A2B0062928A":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"CFNetwork.framework","path":"System/Library/Frameworks/CFNetwork.framework","sourceTree":"SDKROOT"},"301BF5BC109A6A2B0062928A_comment":"CFNetwork.framework","301BF5BE109A6A2B0062928A":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"CoreLocation.framework","path":"System/Library/Frameworks/CoreLocation.framework","sourceTree":"SDKROOT"},"301BF5BE109A6A2B0062928A_comment":"CoreLocation.framework","301BF5C0109A6A2B0062928A":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"MediaPlayer.framework","path":"System/Library/Frameworks/MediaPlayer.framework","sourceTree":"SDKROOT"},"301BF5C0109A6A2B0062928A_comment":"MediaPlayer.framework","301BF5C2109A6A2B0062928A":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"QuartzCore.framework","path":"System/Library/Frameworks/QuartzCore.framework","sourceTree":"SDKROOT"},"301BF5C2109A6A2B0062928A_comment":"QuartzCore.framework","301BF5C4109A6A2B0062928A":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"SystemConfiguration.framework","path":"System/Library/Frameworks/SystemConfiguration.framework","sourceTree":"SDKROOT"},"301BF5C4109A6A2B0062928A_comment":"SystemConfiguration.framework","3053AC6E109B7857006FCFE7":{"isa":"PBXFileReference","fileEncoding":4,"lastKnownFileType":"text","path":"VERSION","sourceTree":"PHONEGAPLIB"},"3053AC6E109B7857006FCFE7_comment":"VERSION","305D5FD0115AB8F900A74A75":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"MobileCoreServices.framework","path":"System/Library/Frameworks/MobileCoreServices.framework","sourceTree":"SDKROOT"},"305D5FD0115AB8F900A74A75_comment":"MobileCoreServices.framework","3072F99613A8081B00425683":{"isa":"PBXFileReference","lastKnownFileType":"\"wrapper.plug-in\"","name":"Capture.bundle","path":"Resources/Capture.bundle","sourceTree":"\"\""},"3072F99613A8081B00425683_comment":"Capture.bundle","307D28A1123043350040C0FA":{"isa":"PBXFileReference","fileEncoding":4,"lastKnownFileType":"text.xcconfig","path":"PhoneGapBuildSettings.xcconfig","sourceTree":"\"\""},"307D28A1123043350040C0FA_comment":"PhoneGapBuildSettings.xcconfig","308D052E1370CCF300D202BF":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"icon-72.png\"","sourceTree":"\"\""},"308D052E1370CCF300D202BF_comment":"icon-72.png","308D052F1370CCF300D202BF":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"icon.png","sourceTree":"\"\""},"308D052F1370CCF300D202BF_comment":"icon.png","308D05301370CCF300D202BF":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"icon@2x.png\"","sourceTree":"\"\""},"308D05301370CCF300D202BF_comment":"icon@2x.png","308D05341370CCF300D202BF":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"Default.png","sourceTree":"\"\""},"308D05341370CCF300D202BF_comment":"Default.png","308D05351370CCF300D202BF":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"Default@2x.png\"","sourceTree":"\"\""},"308D05351370CCF300D202BF_comment":"Default@2x.png","30E1352610E2C1420031B30D":{"isa":"PBXFileReference","fileEncoding":4,"lastKnownFileType":"text.plist.xml","path":"PhoneGap.plist","sourceTree":"\"\""},"30E1352610E2C1420031B30D_comment":"PhoneGap.plist","30E5649113A7FCAF007403D8":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"CoreMedia.framework","path":"System/Library/Frameworks/CoreMedia.framework","sourceTree":"SDKROOT"},"30E5649113A7FCAF007403D8_comment":"CoreMedia.framework","32CA4F630368D1EE00C91783":{"isa":"PBXFileReference","fileEncoding":4,"lastKnownFileType":"sourcecode.c.h","path":"\"KitchenSinktablet-Prefix.pch\"","sourceTree":"\"\""},"32CA4F630368D1EE00C91783_comment":"KitchenSinktablet-Prefix.pch","8D1107310486CEB800E47090":{"isa":"PBXFileReference","fileEncoding":4,"lastKnownFileType":"text.plist.xml","path":"\"KitchenSinktablet-Info.plist\"","plistStructureDefinitionIdentifier":"\"com.apple.xcode.plist.structure-definition.iphone.info-plist\"","sourceTree":"\"\""},"8D1107310486CEB800E47090_comment":"KitchenSinktablet-Info.plist"},"PBXFrameworksBuildPhase":{"1D60588F0D05DD3D006BFB54":{"isa":"PBXFrameworksBuildPhase","buildActionMask":2147483647,"files":[{"value":"301BF552109A68D80062928A","comment":"libPhoneGap.a in Frameworks"},{"value":"1D60589F0D05DD5A006BFB54","comment":"Foundation.framework in Frameworks"},{"value":"1DF5F4E00D08C38300B7A737","comment":"UIKit.framework in Frameworks"},{"value":"288765FD0DF74451002DB57D","comment":"CoreGraphics.framework in Frameworks"},{"value":"301BF5B5109A6A2B0062928A","comment":"AddressBook.framework in Frameworks"},{"value":"301BF5B7109A6A2B0062928A","comment":"AddressBookUI.framework in Frameworks"},{"value":"301BF5B9109A6A2B0062928A","comment":"AudioToolbox.framework in Frameworks"},{"value":"301BF5BB109A6A2B0062928A","comment":"AVFoundation.framework in Frameworks"},{"value":"301BF5BD109A6A2B0062928A","comment":"CFNetwork.framework in Frameworks"},{"value":"301BF5BF109A6A2B0062928A","comment":"CoreLocation.framework in Frameworks"},{"value":"301BF5C1109A6A2B0062928A","comment":"MediaPlayer.framework in Frameworks"},{"value":"301BF5C3109A6A2B0062928A","comment":"QuartzCore.framework in Frameworks"},{"value":"301BF5C5109A6A2B0062928A","comment":"SystemConfiguration.framework in Frameworks"},{"value":"305D5FD1115AB8F900A74A75","comment":"MobileCoreServices.framework in Frameworks"},{"value":"30E5649213A7FCAF007403D8","comment":"CoreMedia.framework in Frameworks"}],"runOnlyForDeploymentPostprocessing":0},"1D60588F0D05DD3D006BFB54_comment":"Frameworks"},"PBXGroup":{"080E96DDFE201D6D7F000001":{"isa":"PBXGroup","children":[{"value":"1D3623240D0F684500981E51","comment":"AppDelegate.h"},{"value":"1D3623250D0F684500981E51","comment":"AppDelegate.m"}],"path":"Classes","sourceTree":"SOURCE_ROOT"},"080E96DDFE201D6D7F000001_comment":"Classes","19C28FACFE9D520D11CA2CBB":{"isa":"PBXGroup","children":[{"value":"1D6058910D05DD3D006BFB54","comment":"KitchenSinktablet.app"}],"name":"Products","sourceTree":"\"\""},"19C28FACFE9D520D11CA2CBB_comment":"Products","1F766FDB13BBADB100FB74C0":{"isa":"PBXGroup","children":[{"value":"1F766FDC13BBADB100FB74C0","comment":"Localizable.strings"}],"name":"en.lproj","path":"Resources/en.lproj","sourceTree":"\"\""},"1F766FDB13BBADB100FB74C0_comment":"en.lproj","1F766FDE13BBADB100FB74C0":{"isa":"PBXGroup","children":[{"value":"1F766FDF13BBADB100FB74C0","comment":"Localizable.strings"}],"name":"es.lproj","path":"Resources/es.lproj","sourceTree":"\"\""},"1F766FDE13BBADB100FB74C0_comment":"es.lproj","29B97314FDCFA39411CA2CEA":{"isa":"PBXGroup","children":[{"value":"301BF56E109A69640062928A","comment":"www"},{"value":"301BF52D109A57CC0062928A","comment":"PhoneGapLib.xcodeproj"},{"value":"080E96DDFE201D6D7F000001","comment":"Classes"},{"value":"307C750510C5A3420062BCA9","comment":"Plugins"},{"value":"29B97315FDCFA39411CA2CEA","comment":"Other Sources"},{"value":"29B97317FDCFA39411CA2CEA","comment":"Resources"},{"value":"29B97323FDCFA39411CA2CEA","comment":"Frameworks"},{"value":"19C28FACFE9D520D11CA2CBB","comment":"Products"}],"name":"CustomTemplate","sourceTree":"\"\""},"29B97314FDCFA39411CA2CEA_comment":"CustomTemplate","29B97315FDCFA39411CA2CEA":{"isa":"PBXGroup","children":[{"value":"32CA4F630368D1EE00C91783","comment":"KitchenSinktablet-Prefix.pch"},{"value":"29B97316FDCFA39411CA2CEA","comment":"main.m"}],"name":"\"Other Sources\"","sourceTree":"\"\""},"29B97315FDCFA39411CA2CEA_comment":"Other Sources","29B97317FDCFA39411CA2CEA":{"isa":"PBXGroup","children":[{"value":"1F766FDB13BBADB100FB74C0","comment":"en.lproj"},{"value":"1F766FDE13BBADB100FB74C0","comment":"es.lproj"},{"value":"3072F99613A8081B00425683","comment":"Capture.bundle"},{"value":"308D052D1370CCF300D202BF","comment":"icons"},{"value":"308D05311370CCF300D202BF","comment":"splash"},{"value":"30E1352610E2C1420031B30D","comment":"PhoneGap.plist"},{"value":"3053AC6E109B7857006FCFE7","comment":"VERSION"},{"value":"8D1107310486CEB800E47090","comment":"KitchenSinktablet-Info.plist"},{"value":"307D28A1123043350040C0FA","comment":"PhoneGapBuildSettings.xcconfig"}],"name":"Resources","sourceTree":"\"\""},"29B97317FDCFA39411CA2CEA_comment":"Resources","29B97323FDCFA39411CA2CEA":{"isa":"PBXGroup","children":[{"value":"1DF5F4DF0D08C38300B7A737","comment":"UIKit.framework"},{"value":"1D30AB110D05D00D00671497","comment":"Foundation.framework"},{"value":"288765FC0DF74451002DB57D","comment":"CoreGraphics.framework"},{"value":"301BF5B4109A6A2B0062928A","comment":"AddressBook.framework"},{"value":"301BF5B6109A6A2B0062928A","comment":"AddressBookUI.framework"},{"value":"301BF5B8109A6A2B0062928A","comment":"AudioToolbox.framework"},{"value":"301BF5BA109A6A2B0062928A","comment":"AVFoundation.framework"},{"value":"301BF5BC109A6A2B0062928A","comment":"CFNetwork.framework"},{"value":"301BF5BE109A6A2B0062928A","comment":"CoreLocation.framework"},{"value":"301BF5C0109A6A2B0062928A","comment":"MediaPlayer.framework"},{"value":"301BF5C2109A6A2B0062928A","comment":"QuartzCore.framework"},{"value":"301BF5C4109A6A2B0062928A","comment":"SystemConfiguration.framework"},{"value":"305D5FD0115AB8F900A74A75","comment":"MobileCoreServices.framework"},{"value":"30E5649113A7FCAF007403D8","comment":"CoreMedia.framework"}],"name":"Frameworks","sourceTree":"\"\""},"29B97323FDCFA39411CA2CEA_comment":"Frameworks","301BF52E109A57CC0062928A":{"isa":"PBXGroup","children":[{"value":"301BF535109A57CC0062928A","comment":"libPhoneGap.a"},{"value":"30E47BC3136F595F00DBB853","comment":"PhoneGap.framework"}],"name":"Products","sourceTree":"\"\""},"301BF52E109A57CC0062928A_comment":"Products","307C750510C5A3420062BCA9":{"isa":"PBXGroup","children":[],"path":"Plugins","sourceTree":"SOURCE_ROOT"},"307C750510C5A3420062BCA9_comment":"Plugins","308D052D1370CCF300D202BF":{"isa":"PBXGroup","children":[{"value":"308D052E1370CCF300D202BF","comment":"icon-72.png"},{"value":"308D052F1370CCF300D202BF","comment":"icon.png"},{"value":"308D05301370CCF300D202BF","comment":"icon@2x.png"}],"name":"icons","path":"Resources/icons","sourceTree":"\"\""},"308D052D1370CCF300D202BF_comment":"icons","308D05311370CCF300D202BF":{"isa":"PBXGroup","children":[{"value":"308D05341370CCF300D202BF","comment":"Default.png"},{"value":"308D05351370CCF300D202BF","comment":"Default@2x.png"}],"name":"splash","path":"Resources/splash","sourceTree":"\"\""},"308D05311370CCF300D202BF_comment":"splash"},"PBXNativeTarget":{"1D6058900D05DD3D006BFB54":{"isa":"PBXNativeTarget","buildConfigurationList":"1D6058960D05DD3E006BFB54","buildConfigurationList_comment":"Build configuration list for PBXNativeTarget \"KitchenSinktablet\"","buildPhases":[{"value":"304B58A110DAC018002A0835","comment":"Touch www folder"},{"value":"1D60588D0D05DD3D006BFB54","comment":"Resources"},{"value":"1D60588E0D05DD3D006BFB54","comment":"Sources"},{"value":"1D60588F0D05DD3D006BFB54","comment":"Frameworks"}],"buildRules":[],"dependencies":[{"value":"301BF551109A68C00062928A","comment":"PBXTargetDependency"}],"name":"\"KitchenSinktablet\"","productName":"\"KitchenSinktablet\"","productReference":"1D6058910D05DD3D006BFB54","productReference_comment":"KitchenSinktablet.app","productType":"\"com.apple.product-type.application\""},"1D6058900D05DD3D006BFB54_comment":"KitchenSinktablet"},"PBXProject":{"29B97313FDCFA39411CA2CEA":{"isa":"PBXProject","buildConfigurationList":"C01FCF4E08A954540054247B","buildConfigurationList_comment":"Build configuration list for PBXProject \"KitchenSinktablet\"","compatibilityVersion":"\"Xcode 3.1\"","developmentRegion":"English","hasScannedForEncodings":1,"knownRegions":["English","Japanese","French","German","en","es"],"mainGroup":"29B97314FDCFA39411CA2CEA","mainGroup_comment":"CustomTemplate","projectDirPath":"\"\"","projectReferences":[{"ProductGroup":"301BF52E109A57CC0062928A","ProductGroup_comment":"Products","ProjectRef":"301BF52D109A57CC0062928A","ProjectRef_comment":"PhoneGapLib.xcodeproj"}],"projectRoot":"\"\"","targets":[{"value":"1D6058900D05DD3D006BFB54","comment":"KitchenSinktablet"}]},"29B97313FDCFA39411CA2CEA_comment":"Project object"},"PBXReferenceProxy":{"301BF535109A57CC0062928A":{"isa":"PBXReferenceProxy","fileType":"archive.ar","path":"libPhoneGap.a","remoteRef":"301BF534109A57CC0062928A","remoteRef_comment":"PBXContainerItemProxy","sourceTree":"BUILT_PRODUCTS_DIR"},"301BF535109A57CC0062928A_comment":"libPhoneGap.a","30E47BC3136F595F00DBB853":{"isa":"PBXReferenceProxy","fileType":"wrapper.cfbundle","path":"PhoneGap.framework","remoteRef":"30E47BC2136F595F00DBB853","remoteRef_comment":"PBXContainerItemProxy","sourceTree":"BUILT_PRODUCTS_DIR"},"30E47BC3136F595F00DBB853_comment":"PhoneGap.framework"},"PBXResourcesBuildPhase":{"1D60588D0D05DD3D006BFB54":{"isa":"PBXResourcesBuildPhase","buildActionMask":2147483647,"files":[{"value":"301BF570109A69640062928A","comment":"www in Resources"},{"value":"3053AC6F109B7857006FCFE7","comment":"VERSION in Resources"},{"value":"30E1352710E2C1420031B30D","comment":"PhoneGap.plist in Resources"},{"value":"307D28A2123043360040C0FA","comment":"PhoneGapBuildSettings.xcconfig in Resources"},{"value":"308D05371370CCF300D202BF","comment":"icon-72.png in Resources"},{"value":"308D05381370CCF300D202BF","comment":"icon.png in Resources"},{"value":"308D05391370CCF300D202BF","comment":"icon@2x.png in Resources"},{"value":"308D053C1370CCF300D202BF","comment":"Default.png in Resources"},{"value":"308D053D1370CCF300D202BF","comment":"Default@2x.png in Resources"},{"value":"3072F99713A8081B00425683","comment":"Capture.bundle in Resources"},{"value":"1F766FE113BBADB100FB74C0","comment":"Localizable.strings in Resources"},{"value":"1F766FE213BBADB100FB74C0","comment":"Localizable.strings in Resources"}],"runOnlyForDeploymentPostprocessing":0},"1D60588D0D05DD3D006BFB54_comment":"Resources"},"PBXShellScriptBuildPhase":{"304B58A110DAC018002A0835":{"isa":"PBXShellScriptBuildPhase","buildActionMask":2147483647,"files":[],"inputPaths":[],"name":"\"Touch www folder\"","outputPaths":[],"runOnlyForDeploymentPostprocessing":0,"shellPath":"/bin/sh","shellScript":"\"touch -cm ${PROJECT_DIR}/www\""},"304B58A110DAC018002A0835_comment":"Touch www folder"},"PBXSourcesBuildPhase":{"1D60588E0D05DD3D006BFB54":{"isa":"PBXSourcesBuildPhase","buildActionMask":2147483647,"files":[{"value":"1D60589B0D05DD56006BFB54","comment":"main.m in Sources"},{"value":"1D3623260D0F684500981E51","comment":"AppDelegate.m in Sources"}],"runOnlyForDeploymentPostprocessing":0},"1D60588E0D05DD3D006BFB54_comment":"Sources"},"PBXTargetDependency":{"301BF551109A68C00062928A":{"isa":"PBXTargetDependency","name":"PhoneGapLib","targetProxy":"301BF550109A68C00062928A","targetProxy_comment":"PBXContainerItemProxy"},"301BF551109A68C00062928A_comment":"PBXTargetDependency"},"PBXVariantGroup":{"1F766FDC13BBADB100FB74C0":{"isa":"PBXVariantGroup","children":[{"value":"1F766FDD13BBADB100FB74C0","comment":"en"}],"name":"Localizable.strings","sourceTree":"\"\""},"1F766FDC13BBADB100FB74C0_comment":"Localizable.strings","1F766FDF13BBADB100FB74C0":{"isa":"PBXVariantGroup","children":[{"value":"1F766FE013BBADB100FB74C0","comment":"es"}],"name":"Localizable.strings","sourceTree":"\"\""},"1F766FDF13BBADB100FB74C0_comment":"Localizable.strings"},"XCBuildConfiguration":{"1D6058940D05DD3E006BFB54":{"isa":"XCBuildConfiguration","buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","ARCHS":["armv6","armv7"],"COPY_PHASE_STRIP":"NO","GCC_DYNAMIC_NO_PIC":"NO","GCC_OPTIMIZATION_LEVEL":0,"GCC_PRECOMPILE_PREFIX_HEADER":"YES","GCC_PREFIX_HEADER":"\"KitchenSinktablet-Prefix.pch\"","INFOPLIST_FILE":"\"KitchenSinktablet-Info.plist\"","IPHONEOS_DEPLOYMENT_TARGET":"3.0","ONLY_ACTIVE_ARCH":"NO","PRODUCT_NAME":"\"KitchenSinktablet\"","TARGETED_DEVICE_FAMILY":"\"1,2\""},"name":"Debug"},"1D6058940D05DD3E006BFB54_comment":"Debug","1D6058950D05DD3E006BFB54":{"isa":"XCBuildConfiguration","buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","ARCHS":["armv6","armv7"],"COPY_PHASE_STRIP":"YES","GCC_PRECOMPILE_PREFIX_HEADER":"YES","GCC_PREFIX_HEADER":"\"KitchenSinktablet-Prefix.pch\"","INFOPLIST_FILE":"\"KitchenSinktablet-Info.plist\"","IPHONEOS_DEPLOYMENT_TARGET":"3.0","ONLY_ACTIVE_ARCH":"NO","PRODUCT_NAME":"\"KitchenSinktablet\"","TARGETED_DEVICE_FAMILY":"\"1,2\""},"name":"Release"},"1D6058950D05DD3E006BFB54_comment":"Release","C01FCF4F08A954540054247B":{"isa":"XCBuildConfiguration","baseConfigurationReference":"307D28A1123043350040C0FA","baseConfigurationReference_comment":"PhoneGapBuildSettings.xcconfig","buildSettings":{"ARCHS":"\"$(ARCHS_STANDARD_32_BIT)\"","\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\"":"\"iPhone Distribution\"","GCC_C_LANGUAGE_STANDARD":"c99","GCC_VERSION":"com.apple.compilers.llvmgcc42","GCC_WARN_ABOUT_RETURN_TYPE":"YES","GCC_WARN_UNUSED_VARIABLE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"3.0","OTHER_LDFLAGS":["\"-weak_framework\"","UIKit","\"-weak_framework\"","AVFoundation","\"-weak_framework\"","CoreMedia","\"-weak_library\"","/usr/lib/libSystem.B.dylib","\"-all_load\"","\"-Obj-C\""],"PREBINDING":"NO","SDKROOT":"iphoneos","SKIP_INSTALL":"NO","USER_HEADER_SEARCH_PATHS":"\"\"$(PHONEGAPLIB)/Classes/JSON\" \"$(PHONEGAPLIB)/Classes\"\""},"name":"Debug"},"C01FCF4F08A954540054247B_comment":"Debug","C01FCF5008A954540054247B":{"isa":"XCBuildConfiguration","baseConfigurationReference":"307D28A1123043350040C0FA","baseConfigurationReference_comment":"PhoneGapBuildSettings.xcconfig","buildSettings":{"ARCHS":"\"$(ARCHS_STANDARD_32_BIT)\"","\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\"":"\"iPhone Distribution\"","GCC_C_LANGUAGE_STANDARD":"c99","GCC_VERSION":"com.apple.compilers.llvmgcc42","GCC_WARN_ABOUT_RETURN_TYPE":"YES","GCC_WARN_UNUSED_VARIABLE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"3.0","OTHER_LDFLAGS":["\"-weak_framework\"","UIKit","\"-weak_framework\"","AVFoundation","\"-weak_framework\"","CoreMedia","\"-weak_library\"","/usr/lib/libSystem.B.dylib","\"-all_load\"","\"-Obj-C\""],"PREBINDING":"NO","SDKROOT":"iphoneos","SKIP_INSTALL":"NO","USER_HEADER_SEARCH_PATHS":"\"\"$(PHONEGAPLIB)/Classes/JSON\" \"$(PHONEGAPLIB)/Classes\"\""},"name":"Release"},"C01FCF5008A954540054247B_comment":"Release"},"XCConfigurationList":{"1D6058960D05DD3E006BFB54":{"isa":"XCConfigurationList","buildConfigurations":[{"value":"1D6058940D05DD3E006BFB54","comment":"Debug"},{"value":"1D6058950D05DD3E006BFB54","comment":"Release"}],"defaultConfigurationIsVisible":0,"defaultConfigurationName":"Release"},"1D6058960D05DD3E006BFB54_comment":"Build configuration list for PBXNativeTarget \"KitchenSinktablet\"","C01FCF4E08A954540054247B":{"isa":"XCConfigurationList","buildConfigurations":[{"value":"C01FCF4F08A954540054247B","comment":"Debug"},{"value":"C01FCF5008A954540054247B","comment":"Release"}],"defaultConfigurationIsVisible":0,"defaultConfigurationName":"Release"},"C01FCF4E08A954540054247B_comment":"Build configuration list for PBXProject \"KitchenSinktablet\""}},"rootObject":"29B97313FDCFA39411CA2CEA","rootObject_comment":"Project object"},"headComment":"!$*UTF8*$!"} +{ + "project": { + "archiveVersion": 1, + "classes": {}, + "objectVersion": 45, + "objects": { + "PBXBuildFile": { + "1D3623260D0F684500981E51": { + "isa": "PBXBuildFile", + "fileRef": "1D3623250D0F684500981E51", + "fileRef_comment": "AppDelegate.m" + }, + "1D3623260D0F684500981E51_comment": "AppDelegate.m in Sources", + "1D60589B0D05DD56006BFB54": { + "isa": "PBXBuildFile", + "fileRef": "29B97316FDCFA39411CA2CEA", + "fileRef_comment": "main.m" + }, + "1D60589B0D05DD56006BFB54_comment": "main.m in Sources", + "1D60589F0D05DD5A006BFB54": { + "isa": "PBXBuildFile", + "fileRef": "1D30AB110D05D00D00671497", + "fileRef_comment": "Foundation.framework" + }, + "1D60589F0D05DD5A006BFB54_comment": "Foundation.framework in Frameworks", + "1DF5F4E00D08C38300B7A737": { + "isa": "PBXBuildFile", + "fileRef": "1DF5F4DF0D08C38300B7A737", + "fileRef_comment": "UIKit.framework", + "settings": { + "ATTRIBUTES": [ + "Weak" + ] + } + }, + "1DF5F4E00D08C38300B7A737_comment": "UIKit.framework in Frameworks", + "1F766FE113BBADB100FB74C0": { + "isa": "PBXBuildFile", + "fileRef": "1F766FDC13BBADB100FB74C0", + "fileRef_comment": "Localizable.strings" + }, + "1F766FE113BBADB100FB74C0_comment": "Localizable.strings in Resources", + "1F766FE213BBADB100FB74C0": { + "isa": "PBXBuildFile", + "fileRef": "1F766FDF13BBADB100FB74C0", + "fileRef_comment": "Localizable.strings" + }, + "1F766FE213BBADB100FB74C0_comment": "Localizable.strings in Resources", + "288765FD0DF74451002DB57D": { + "isa": "PBXBuildFile", + "fileRef": "288765FC0DF74451002DB57D", + "fileRef_comment": "CoreGraphics.framework" + }, + "288765FD0DF74451002DB57D_comment": "CoreGraphics.framework in Frameworks", + "301BF552109A68D80062928A": { + "isa": "PBXBuildFile", + "fileRef": "301BF535109A57CC0062928A", + "fileRef_comment": "libPhoneGap.a" + }, + "301BF552109A68D80062928A_comment": "libPhoneGap.a in Frameworks", + "301BF570109A69640062928A": { + "isa": "PBXBuildFile", + "fileRef": "301BF56E109A69640062928A", + "fileRef_comment": "www" + }, + "301BF570109A69640062928A_comment": "www in Resources", + "301BF5B5109A6A2B0062928A": { + "isa": "PBXBuildFile", + "fileRef": "301BF5B4109A6A2B0062928A", + "fileRef_comment": "AddressBook.framework" + }, + "301BF5B5109A6A2B0062928A_comment": "AddressBook.framework in Frameworks", + "301BF5B7109A6A2B0062928A": { + "isa": "PBXBuildFile", + "fileRef": "301BF5B6109A6A2B0062928A", + "fileRef_comment": "AddressBookUI.framework" + }, + "301BF5B7109A6A2B0062928A_comment": "AddressBookUI.framework in Frameworks", + "301BF5B9109A6A2B0062928A": { + "isa": "PBXBuildFile", + "fileRef": "301BF5B8109A6A2B0062928A", + "fileRef_comment": "AudioToolbox.framework" + }, + "301BF5B9109A6A2B0062928A_comment": "AudioToolbox.framework in Frameworks", + "301BF5BB109A6A2B0062928A": { + "isa": "PBXBuildFile", + "fileRef": "301BF5BA109A6A2B0062928A", + "fileRef_comment": "AVFoundation.framework", + "settings": { + "ATTRIBUTES": [ + "Weak" + ] + } + }, + "301BF5BB109A6A2B0062928A_comment": "AVFoundation.framework in Frameworks", + "301BF5BD109A6A2B0062928A": { + "isa": "PBXBuildFile", + "fileRef": "301BF5BC109A6A2B0062928A", + "fileRef_comment": "CFNetwork.framework" + }, + "301BF5BD109A6A2B0062928A_comment": "CFNetwork.framework in Frameworks", + "301BF5BF109A6A2B0062928A": { + "isa": "PBXBuildFile", + "fileRef": "301BF5BE109A6A2B0062928A", + "fileRef_comment": "CoreLocation.framework" + }, + "301BF5BF109A6A2B0062928A_comment": "CoreLocation.framework in Frameworks", + "301BF5C1109A6A2B0062928A": { + "isa": "PBXBuildFile", + "fileRef": "301BF5C0109A6A2B0062928A", + "fileRef_comment": "MediaPlayer.framework" + }, + "301BF5C1109A6A2B0062928A_comment": "MediaPlayer.framework in Frameworks", + "301BF5C3109A6A2B0062928A": { + "isa": "PBXBuildFile", + "fileRef": "301BF5C2109A6A2B0062928A", + "fileRef_comment": "QuartzCore.framework" + }, + "301BF5C3109A6A2B0062928A_comment": "QuartzCore.framework in Frameworks", + "301BF5C5109A6A2B0062928A": { + "isa": "PBXBuildFile", + "fileRef": "301BF5C4109A6A2B0062928A", + "fileRef_comment": "SystemConfiguration.framework" + }, + "301BF5C5109A6A2B0062928A_comment": "SystemConfiguration.framework in Frameworks", + "3053AC6F109B7857006FCFE7": { + "isa": "PBXBuildFile", + "fileRef": "3053AC6E109B7857006FCFE7", + "fileRef_comment": "VERSION" + }, + "3053AC6F109B7857006FCFE7_comment": "VERSION in Resources", + "305D5FD1115AB8F900A74A75": { + "isa": "PBXBuildFile", + "fileRef": "305D5FD0115AB8F900A74A75", + "fileRef_comment": "MobileCoreServices.framework" + }, + "305D5FD1115AB8F900A74A75_comment": "MobileCoreServices.framework in Frameworks", + "3072F99713A8081B00425683": { + "isa": "PBXBuildFile", + "fileRef": "3072F99613A8081B00425683", + "fileRef_comment": "Capture.bundle" + }, + "3072F99713A8081B00425683_comment": "Capture.bundle in Resources", + "307D28A2123043360040C0FA": { + "isa": "PBXBuildFile", + "fileRef": "307D28A1123043350040C0FA", + "fileRef_comment": "PhoneGapBuildSettings.xcconfig" + }, + "307D28A2123043360040C0FA_comment": "PhoneGapBuildSettings.xcconfig in Resources", + "308D05371370CCF300D202BF": { + "isa": "PBXBuildFile", + "fileRef": "308D052E1370CCF300D202BF", + "fileRef_comment": "icon-72.png" + }, + "308D05371370CCF300D202BF_comment": "icon-72.png in Resources", + "308D05381370CCF300D202BF": { + "isa": "PBXBuildFile", + "fileRef": "308D052F1370CCF300D202BF", + "fileRef_comment": "icon.png" + }, + "308D05381370CCF300D202BF_comment": "icon.png in Resources", + "308D05391370CCF300D202BF": { + "isa": "PBXBuildFile", + "fileRef": "308D05301370CCF300D202BF", + "fileRef_comment": "icon@2x.png" + }, + "308D05391370CCF300D202BF_comment": "icon@2x.png in Resources", + "308D053C1370CCF300D202BF": { + "isa": "PBXBuildFile", + "fileRef": "308D05341370CCF300D202BF", + "fileRef_comment": "Default.png" + }, + "308D053C1370CCF300D202BF_comment": "Default.png in Resources", + "308D053D1370CCF300D202BF": { + "isa": "PBXBuildFile", + "fileRef": "308D05351370CCF300D202BF", + "fileRef_comment": "Default@2x.png" + }, + "308D053D1370CCF300D202BF_comment": "Default@2x.png in Resources", + "30E1352710E2C1420031B30D": { + "isa": "PBXBuildFile", + "fileRef": "30E1352610E2C1420031B30D", + "fileRef_comment": "PhoneGap.plist" + }, + "30E1352710E2C1420031B30D_comment": "PhoneGap.plist in Resources", + "30E5649213A7FCAF007403D8": { + "isa": "PBXBuildFile", + "fileRef": "30E5649113A7FCAF007403D8", + "fileRef_comment": "CoreMedia.framework", + "settings": { + "ATTRIBUTES": [ + "Weak" + ] + } + }, + "30E5649213A7FCAF007403D8_comment": "CoreMedia.framework in Frameworks" + }, + "PBXContainerItemProxy": { + "301BF534109A57CC0062928A": { + "isa": "PBXContainerItemProxy", + "containerPortal": "301BF52D109A57CC0062928A", + "containerPortal_comment": "PhoneGapLib.xcodeproj", + "proxyType": 2, + "remoteGlobalIDString": "D2AAC07E0554694100DB518D", + "remoteInfo": "PhoneGapLib" + }, + "301BF534109A57CC0062928A_comment": "PBXContainerItemProxy", + "301BF550109A68C00062928A": { + "isa": "PBXContainerItemProxy", + "containerPortal": "301BF52D109A57CC0062928A", + "containerPortal_comment": "PhoneGapLib.xcodeproj", + "proxyType": 1, + "remoteGlobalIDString": "D2AAC07D0554694100DB518D", + "remoteInfo": "PhoneGapLib" + }, + "301BF550109A68C00062928A_comment": "PBXContainerItemProxy", + "30E47BC2136F595F00DBB853": { + "isa": "PBXContainerItemProxy", + "containerPortal": "301BF52D109A57CC0062928A", + "containerPortal_comment": "PhoneGapLib.xcodeproj", + "proxyType": 2, + "remoteGlobalIDString": "303258D8136B2C9400982B63", + "remoteInfo": "PhoneGap" + }, + "30E47BC2136F595F00DBB853_comment": "PBXContainerItemProxy" + }, + "PBXCopyFilesBuildPhase": { + "73E82FF51BCF133B004E733B": { + "isa": "PBXCopyFilesBuildPhase", + "buildActionMask": 2147483647, + "dstPath": "\"\"", + "dstSubfolderSpec": 10, + "files": [], + "name": "\"Embed Frameworks\"", + "runOnlyForDeploymentPostprocessing": 0 + }, + "73E82FF51BCF133B004E733B_comment": "Embed Frameworks" + }, + "PBXFileReference": { + "1D30AB110D05D00D00671497": { + "isa": "PBXFileReference", + "lastKnownFileType": "wrapper.framework", + "name": "Foundation.framework", + "path": "System/Library/Frameworks/Foundation.framework", + "sourceTree": "SDKROOT" + }, + "1D30AB110D05D00D00671497_comment": "Foundation.framework", + "1D3623240D0F684500981E51": { + "isa": "PBXFileReference", + "fileEncoding": 4, + "lastKnownFileType": "sourcecode.c.h", + "path": "AppDelegate.h", + "sourceTree": "\"\"" + }, + "1D3623240D0F684500981E51_comment": "AppDelegate.h", + "1D3623250D0F684500981E51": { + "isa": "PBXFileReference", + "fileEncoding": 4, + "lastKnownFileType": "sourcecode.c.objc", + "path": "AppDelegate.m", + "sourceTree": "\"\"" + }, + "1D3623250D0F684500981E51_comment": "AppDelegate.m", + "1D6058910D05DD3D006BFB54": { + "isa": "PBXFileReference", + "explicitFileType": "wrapper.application", + "includeInIndex": 0, + "path": "\"KitchenSinktablet.app\"", + "sourceTree": "BUILT_PRODUCTS_DIR" + }, + "1D6058910D05DD3D006BFB54_comment": "KitchenSinktablet.app", + "1DF5F4DF0D08C38300B7A737": { + "isa": "PBXFileReference", + "lastKnownFileType": "wrapper.framework", + "name": "UIKit.framework", + "path": "System/Library/Frameworks/UIKit.framework", + "sourceTree": "SDKROOT" + }, + "1DF5F4DF0D08C38300B7A737_comment": "UIKit.framework", + "1F766FDD13BBADB100FB74C0": { + "isa": "PBXFileReference", + "lastKnownFileType": "text.plist.strings", + "name": "en", + "path": "Localizable.strings", + "sourceTree": "\"\"" + }, + "1F766FDD13BBADB100FB74C0_comment": "en", + "1F766FE013BBADB100FB74C0": { + "isa": "PBXFileReference", + "lastKnownFileType": "text.plist.strings", + "name": "es", + "path": "Localizable.strings", + "sourceTree": "\"\"" + }, + "1F766FE013BBADB100FB74C0_comment": "es", + "288765FC0DF74451002DB57D": { + "isa": "PBXFileReference", + "lastKnownFileType": "wrapper.framework", + "name": "CoreGraphics.framework", + "path": "System/Library/Frameworks/CoreGraphics.framework", + "sourceTree": "SDKROOT" + }, + "288765FC0DF74451002DB57D_comment": "CoreGraphics.framework", + "29B97316FDCFA39411CA2CEA": { + "isa": "PBXFileReference", + "fileEncoding": 4, + "lastKnownFileType": "sourcecode.c.objc", + "path": "main.m", + "sourceTree": "\"\"" + }, + "29B97316FDCFA39411CA2CEA_comment": "main.m", + "301BF52D109A57CC0062928A": { + "isa": "PBXFileReference", + "lastKnownFileType": "\"wrapper.pb-project\"", + "path": "PhoneGapLib.xcodeproj", + "sourceTree": "PHONEGAPLIB" + }, + "301BF52D109A57CC0062928A_comment": "PhoneGapLib.xcodeproj", + "301BF56E109A69640062928A": { + "isa": "PBXFileReference", + "lastKnownFileType": "folder", + "path": "www", + "sourceTree": "SOURCE_ROOT" + }, + "301BF56E109A69640062928A_comment": "www", + "301BF5B4109A6A2B0062928A": { + "isa": "PBXFileReference", + "lastKnownFileType": "wrapper.framework", + "name": "AddressBook.framework", + "path": "System/Library/Frameworks/AddressBook.framework", + "sourceTree": "SDKROOT" + }, + "301BF5B4109A6A2B0062928A_comment": "AddressBook.framework", + "301BF5B6109A6A2B0062928A": { + "isa": "PBXFileReference", + "lastKnownFileType": "wrapper.framework", + "name": "AddressBookUI.framework", + "path": "System/Library/Frameworks/AddressBookUI.framework", + "sourceTree": "SDKROOT" + }, + "301BF5B6109A6A2B0062928A_comment": "AddressBookUI.framework", + "301BF5B8109A6A2B0062928A": { + "isa": "PBXFileReference", + "lastKnownFileType": "wrapper.framework", + "name": "AudioToolbox.framework", + "path": "System/Library/Frameworks/AudioToolbox.framework", + "sourceTree": "SDKROOT" + }, + "301BF5B8109A6A2B0062928A_comment": "AudioToolbox.framework", + "301BF5BA109A6A2B0062928A": { + "isa": "PBXFileReference", + "lastKnownFileType": "wrapper.framework", + "name": "AVFoundation.framework", + "path": "System/Library/Frameworks/AVFoundation.framework", + "sourceTree": "SDKROOT" + }, + "301BF5BA109A6A2B0062928A_comment": "AVFoundation.framework", + "301BF5BC109A6A2B0062928A": { + "isa": "PBXFileReference", + "lastKnownFileType": "wrapper.framework", + "name": "CFNetwork.framework", + "path": "System/Library/Frameworks/CFNetwork.framework", + "sourceTree": "SDKROOT" + }, + "301BF5BC109A6A2B0062928A_comment": "CFNetwork.framework", + "301BF5BE109A6A2B0062928A": { + "isa": "PBXFileReference", + "lastKnownFileType": "wrapper.framework", + "name": "CoreLocation.framework", + "path": "System/Library/Frameworks/CoreLocation.framework", + "sourceTree": "SDKROOT" + }, + "301BF5BE109A6A2B0062928A_comment": "CoreLocation.framework", + "301BF5C0109A6A2B0062928A": { + "isa": "PBXFileReference", + "lastKnownFileType": "wrapper.framework", + "name": "MediaPlayer.framework", + "path": "System/Library/Frameworks/MediaPlayer.framework", + "sourceTree": "SDKROOT" + }, + "301BF5C0109A6A2B0062928A_comment": "MediaPlayer.framework", + "301BF5C2109A6A2B0062928A": { + "isa": "PBXFileReference", + "lastKnownFileType": "wrapper.framework", + "name": "QuartzCore.framework", + "path": "System/Library/Frameworks/QuartzCore.framework", + "sourceTree": "SDKROOT" + }, + "301BF5C2109A6A2B0062928A_comment": "QuartzCore.framework", + "301BF5C4109A6A2B0062928A": { + "isa": "PBXFileReference", + "lastKnownFileType": "wrapper.framework", + "name": "SystemConfiguration.framework", + "path": "System/Library/Frameworks/SystemConfiguration.framework", + "sourceTree": "SDKROOT" + }, + "301BF5C4109A6A2B0062928A_comment": "SystemConfiguration.framework", + "3053AC6E109B7857006FCFE7": { + "isa": "PBXFileReference", + "fileEncoding": 4, + "lastKnownFileType": "text", + "path": "VERSION", + "sourceTree": "PHONEGAPLIB" + }, + "3053AC6E109B7857006FCFE7_comment": "VERSION", + "305D5FD0115AB8F900A74A75": { + "isa": "PBXFileReference", + "lastKnownFileType": "wrapper.framework", + "name": "MobileCoreServices.framework", + "path": "System/Library/Frameworks/MobileCoreServices.framework", + "sourceTree": "SDKROOT" + }, + "305D5FD0115AB8F900A74A75_comment": "MobileCoreServices.framework", + "3072F99613A8081B00425683": { + "isa": "PBXFileReference", + "lastKnownFileType": "\"wrapper.plug-in\"", + "name": "Capture.bundle", + "path": "Resources/Capture.bundle", + "sourceTree": "\"\"" + }, + "3072F99613A8081B00425683_comment": "Capture.bundle", + "307D28A1123043350040C0FA": { + "isa": "PBXFileReference", + "fileEncoding": 4, + "lastKnownFileType": "text.xcconfig", + "path": "PhoneGapBuildSettings.xcconfig", + "sourceTree": "\"\"" + }, + "307D28A1123043350040C0FA_comment": "PhoneGapBuildSettings.xcconfig", + "308D052E1370CCF300D202BF": { + "isa": "PBXFileReference", + "lastKnownFileType": "image.png", + "path": "\"icon-72.png\"", + "sourceTree": "\"\"" + }, + "308D052E1370CCF300D202BF_comment": "icon-72.png", + "308D052F1370CCF300D202BF": { + "isa": "PBXFileReference", + "lastKnownFileType": "image.png", + "path": "icon.png", + "sourceTree": "\"\"" + }, + "308D052F1370CCF300D202BF_comment": "icon.png", + "308D05301370CCF300D202BF": { + "isa": "PBXFileReference", + "lastKnownFileType": "image.png", + "path": "\"icon@2x.png\"", + "sourceTree": "\"\"" + }, + "308D05301370CCF300D202BF_comment": "icon@2x.png", + "308D05341370CCF300D202BF": { + "isa": "PBXFileReference", + "lastKnownFileType": "image.png", + "path": "Default.png", + "sourceTree": "\"\"" + }, + "308D05341370CCF300D202BF_comment": "Default.png", + "308D05351370CCF300D202BF": { + "isa": "PBXFileReference", + "lastKnownFileType": "image.png", + "path": "\"Default@2x.png\"", + "sourceTree": "\"\"" + }, + "308D05351370CCF300D202BF_comment": "Default@2x.png", + "30E1352610E2C1420031B30D": { + "isa": "PBXFileReference", + "fileEncoding": 4, + "lastKnownFileType": "text.plist.xml", + "path": "PhoneGap.plist", + "sourceTree": "\"\"" + }, + "30E1352610E2C1420031B30D_comment": "PhoneGap.plist", + "30E5649113A7FCAF007403D8": { + "isa": "PBXFileReference", + "lastKnownFileType": "wrapper.framework", + "name": "CoreMedia.framework", + "path": "System/Library/Frameworks/CoreMedia.framework", + "sourceTree": "SDKROOT" + }, + "30E5649113A7FCAF007403D8_comment": "CoreMedia.framework", + "32CA4F630368D1EE00C91783": { + "isa": "PBXFileReference", + "fileEncoding": 4, + "lastKnownFileType": "sourcecode.c.h", + "path": "\"KitchenSinktablet-Prefix.pch\"", + "sourceTree": "\"\"" + }, + "32CA4F630368D1EE00C91783_comment": "KitchenSinktablet-Prefix.pch", + "8D1107310486CEB800E47090": { + "isa": "PBXFileReference", + "fileEncoding": 4, + "lastKnownFileType": "text.plist.xml", + "path": "\"KitchenSinktablet-Info.plist\"", + "plistStructureDefinitionIdentifier": "\"com.apple.xcode.plist.structure-definition.iphone.info-plist\"", + "sourceTree": "\"\"" + }, + "8D1107310486CEB800E47090_comment": "KitchenSinktablet-Info.plist" + }, + "PBXFrameworksBuildPhase": { + "1D60588F0D05DD3D006BFB54": { + "isa": "PBXFrameworksBuildPhase", + "buildActionMask": 2147483647, + "files": [ + { + "value": "301BF552109A68D80062928A", + "comment": "libPhoneGap.a in Frameworks" + }, + { + "value": "1D60589F0D05DD5A006BFB54", + "comment": "Foundation.framework in Frameworks" + }, + { + "value": "1DF5F4E00D08C38300B7A737", + "comment": "UIKit.framework in Frameworks" + }, + { + "value": "288765FD0DF74451002DB57D", + "comment": "CoreGraphics.framework in Frameworks" + }, + { + "value": "301BF5B5109A6A2B0062928A", + "comment": "AddressBook.framework in Frameworks" + }, + { + "value": "301BF5B7109A6A2B0062928A", + "comment": "AddressBookUI.framework in Frameworks" + }, + { + "value": "301BF5B9109A6A2B0062928A", + "comment": "AudioToolbox.framework in Frameworks" + }, + { + "value": "301BF5BB109A6A2B0062928A", + "comment": "AVFoundation.framework in Frameworks" + }, + { + "value": "301BF5BD109A6A2B0062928A", + "comment": "CFNetwork.framework in Frameworks" + }, + { + "value": "301BF5BF109A6A2B0062928A", + "comment": "CoreLocation.framework in Frameworks" + }, + { + "value": "301BF5C1109A6A2B0062928A", + "comment": "MediaPlayer.framework in Frameworks" + }, + { + "value": "301BF5C3109A6A2B0062928A", + "comment": "QuartzCore.framework in Frameworks" + }, + { + "value": "301BF5C5109A6A2B0062928A", + "comment": "SystemConfiguration.framework in Frameworks" + }, + { + "value": "305D5FD1115AB8F900A74A75", + "comment": "MobileCoreServices.framework in Frameworks" + }, + { + "value": "30E5649213A7FCAF007403D8", + "comment": "CoreMedia.framework in Frameworks" + } + ], + "runOnlyForDeploymentPostprocessing": 0 + }, + "1D60588F0D05DD3D006BFB54_comment": "Frameworks" + }, + "PBXGroup": { + "080E96DDFE201D6D7F000001": { + "isa": "PBXGroup", + "children": [ + { + "value": "1D3623240D0F684500981E51", + "comment": "AppDelegate.h" + }, + { + "value": "1D3623250D0F684500981E51", + "comment": "AppDelegate.m" + } + ], + "path": "Classes", + "sourceTree": "SOURCE_ROOT" + }, + "080E96DDFE201D6D7F000001_comment": "Classes", + "19C28FACFE9D520D11CA2CBB": { + "isa": "PBXGroup", + "children": [ + { + "value": "1D6058910D05DD3D006BFB54", + "comment": "KitchenSinktablet.app" + } + ], + "name": "Products", + "sourceTree": "\"\"" + }, + "19C28FACFE9D520D11CA2CBB_comment": "Products", + "1F766FDB13BBADB100FB74C0": { + "isa": "PBXGroup", + "children": [ + { + "value": "1F766FDC13BBADB100FB74C0", + "comment": "Localizable.strings" + } + ], + "name": "en.lproj", + "path": "Resources/en.lproj", + "sourceTree": "\"\"" + }, + "1F766FDB13BBADB100FB74C0_comment": "en.lproj", + "1F766FDE13BBADB100FB74C0": { + "isa": "PBXGroup", + "children": [ + { + "value": "1F766FDF13BBADB100FB74C0", + "comment": "Localizable.strings" + } + ], + "name": "es.lproj", + "path": "Resources/es.lproj", + "sourceTree": "\"\"" + }, + "1F766FDE13BBADB100FB74C0_comment": "es.lproj", + "29B97314FDCFA39411CA2CEA": { + "isa": "PBXGroup", + "children": [ + { + "value": "301BF56E109A69640062928A", + "comment": "www" + }, + { + "value": "301BF52D109A57CC0062928A", + "comment": "PhoneGapLib.xcodeproj" + }, + { + "value": "080E96DDFE201D6D7F000001", + "comment": "Classes" + }, + { + "value": "307C750510C5A3420062BCA9", + "comment": "Plugins" + }, + { + "value": "29B97315FDCFA39411CA2CEA", + "comment": "Other Sources" + }, + { + "value": "29B97317FDCFA39411CA2CEA", + "comment": "Resources" + }, + { + "value": "29B97323FDCFA39411CA2CEA", + "comment": "Frameworks" + }, + { + "value": "19C28FACFE9D520D11CA2CBB", + "comment": "Products" + } + ], + "name": "CustomTemplate", + "sourceTree": "\"\"" + }, + "29B97314FDCFA39411CA2CEA_comment": "CustomTemplate", + "29B97315FDCFA39411CA2CEA": { + "isa": "PBXGroup", + "children": [ + { + "value": "32CA4F630368D1EE00C91783", + "comment": "KitchenSinktablet-Prefix.pch" + }, + { + "value": "29B97316FDCFA39411CA2CEA", + "comment": "main.m" + } + ], + "name": "\"Other Sources\"", + "sourceTree": "\"\"" + }, + "29B97315FDCFA39411CA2CEA_comment": "Other Sources", + "29B97317FDCFA39411CA2CEA": { + "isa": "PBXGroup", + "children": [ + { + "value": "1F766FDB13BBADB100FB74C0", + "comment": "en.lproj" + }, + { + "value": "1F766FDE13BBADB100FB74C0", + "comment": "es.lproj" + }, + { + "value": "3072F99613A8081B00425683", + "comment": "Capture.bundle" + }, + { + "value": "308D052D1370CCF300D202BF", + "comment": "icons" + }, + { + "value": "308D05311370CCF300D202BF", + "comment": "splash" + }, + { + "value": "30E1352610E2C1420031B30D", + "comment": "PhoneGap.plist" + }, + { + "value": "3053AC6E109B7857006FCFE7", + "comment": "VERSION" + }, + { + "value": "8D1107310486CEB800E47090", + "comment": "KitchenSinktablet-Info.plist" + }, + { + "value": "307D28A1123043350040C0FA", + "comment": "PhoneGapBuildSettings.xcconfig" + } + ], + "name": "Resources", + "sourceTree": "\"\"" + }, + "29B97317FDCFA39411CA2CEA_comment": "Resources", + "29B97323FDCFA39411CA2CEA": { + "isa": "PBXGroup", + "children": [ + { + "value": "1DF5F4DF0D08C38300B7A737", + "comment": "UIKit.framework" + }, + { + "value": "1D30AB110D05D00D00671497", + "comment": "Foundation.framework" + }, + { + "value": "288765FC0DF74451002DB57D", + "comment": "CoreGraphics.framework" + }, + { + "value": "301BF5B4109A6A2B0062928A", + "comment": "AddressBook.framework" + }, + { + "value": "301BF5B6109A6A2B0062928A", + "comment": "AddressBookUI.framework" + }, + { + "value": "301BF5B8109A6A2B0062928A", + "comment": "AudioToolbox.framework" + }, + { + "value": "301BF5BA109A6A2B0062928A", + "comment": "AVFoundation.framework" + }, + { + "value": "301BF5BC109A6A2B0062928A", + "comment": "CFNetwork.framework" + }, + { + "value": "301BF5BE109A6A2B0062928A", + "comment": "CoreLocation.framework" + }, + { + "value": "301BF5C0109A6A2B0062928A", + "comment": "MediaPlayer.framework" + }, + { + "value": "301BF5C2109A6A2B0062928A", + "comment": "QuartzCore.framework" + }, + { + "value": "301BF5C4109A6A2B0062928A", + "comment": "SystemConfiguration.framework" + }, + { + "value": "305D5FD0115AB8F900A74A75", + "comment": "MobileCoreServices.framework" + }, + { + "value": "30E5649113A7FCAF007403D8", + "comment": "CoreMedia.framework" + } + ], + "name": "Frameworks", + "sourceTree": "\"\"" + }, + "29B97323FDCFA39411CA2CEA_comment": "Frameworks", + "301BF52E109A57CC0062928A": { + "isa": "PBXGroup", + "children": [ + { + "value": "301BF535109A57CC0062928A", + "comment": "libPhoneGap.a" + }, + { + "value": "30E47BC3136F595F00DBB853", + "comment": "PhoneGap.framework" + } + ], + "name": "Products", + "sourceTree": "\"\"" + }, + "301BF52E109A57CC0062928A_comment": "Products", + "307C750510C5A3420062BCA9": { + "isa": "PBXGroup", + "children": [], + "path": "Plugins", + "sourceTree": "SOURCE_ROOT" + }, + "307C750510C5A3420062BCA9_comment": "Plugins", + "308D052D1370CCF300D202BF": { + "isa": "PBXGroup", + "children": [ + { + "value": "308D052E1370CCF300D202BF", + "comment": "icon-72.png" + }, + { + "value": "308D052F1370CCF300D202BF", + "comment": "icon.png" + }, + { + "value": "308D05301370CCF300D202BF", + "comment": "icon@2x.png" + } + ], + "name": "icons", + "path": "Resources/icons", + "sourceTree": "\"\"" + }, + "308D052D1370CCF300D202BF_comment": "icons", + "308D05311370CCF300D202BF": { + "isa": "PBXGroup", + "children": [ + { + "value": "308D05341370CCF300D202BF", + "comment": "Default.png" + }, + { + "value": "308D05351370CCF300D202BF", + "comment": "Default@2x.png" + } + ], + "name": "splash", + "path": "Resources/splash", + "sourceTree": "\"\"" + }, + "308D05311370CCF300D202BF_comment": "splash" + }, + "PBXNativeTarget": { + "1D6058900D05DD3D006BFB54": { + "isa": "PBXNativeTarget", + "buildConfigurationList": "1D6058960D05DD3E006BFB54", + "buildConfigurationList_comment": "Build configuration list for PBXNativeTarget \"KitchenSinktablet\"", + "buildPhases": [ + { + "value": "304B58A110DAC018002A0835", + "comment": "Touch www folder" + }, + { + "value": "1D60588D0D05DD3D006BFB54", + "comment": "Resources" + }, + { + "value": "1D60588E0D05DD3D006BFB54", + "comment": "Sources" + }, + { + "value": "1D60588F0D05DD3D006BFB54", + "comment": "Frameworks" + } + ], + "buildRules": [], + "dependencies": [ + { + "value": "301BF551109A68C00062928A", + "comment": "PBXTargetDependency" + } + ], + "name": "\"KitchenSinktablet\"", + "productName": "\"KitchenSinktablet\"", + "productReference": "1D6058910D05DD3D006BFB54", + "productReference_comment": "KitchenSinktablet.app", + "productType": "\"com.apple.product-type.application\"" + }, + "1D6058900D05DD3D006BFB54_comment": "KitchenSinktablet", + "1D6058900D05DD3D006BFB55": { + "isa": "PBXNativeTarget", + "buildConfigurationList": "1D6058960D05DD3E006BFB54", + "buildConfigurationList_comment": "Build configuration list for PBXNativeTarget \"TestApp\"", + "buildPhases": [ + { + "value": "304B58A110DAC018002A0835", + "comment": "Touch www folder" + }, + { + "value": "1D60588D0D05DD3D006BFB54", + "comment": "Resources" + }, + { + "value": "1D60588E0D05DD3D006BFB54", + "comment": "Sources" + }, + { + "value": "1D60588F0D05DD3D006BFB54", + "comment": "Frameworks" + } + ], + "buildRules": [], + "dependencies": [], + "name": "\"TestApp\"", + "productName": "\"TestApp\"", + "productReference": "1D6058910D05DD3D006BFB54", + "productReference_comment": "TestApp.app", + "productType": "\"com.apple.product-type.application\"" + }, + "1D6058900D05DD3D006BFB55_comment": "TestApp" + }, + "PBXProject": { + "29B97313FDCFA39411CA2CEA": { + "isa": "PBXProject", + "buildConfigurationList": "C01FCF4E08A954540054247B", + "buildConfigurationList_comment": "Build configuration list for PBXProject \"KitchenSinktablet\"", + "compatibilityVersion": "\"Xcode 3.1\"", + "developmentRegion": "English", + "hasScannedForEncodings": 1, + "knownRegions": [ + "English", + "Japanese", + "French", + "German", + "en", + "es" + ], + "mainGroup": "29B97314FDCFA39411CA2CEA", + "mainGroup_comment": "CustomTemplate", + "projectDirPath": "\"\"", + "projectReferences": [ + { + "ProductGroup": "301BF52E109A57CC0062928A", + "ProductGroup_comment": "Products", + "ProjectRef": "301BF52D109A57CC0062928A", + "ProjectRef_comment": "PhoneGapLib.xcodeproj" + } + ], + "projectRoot": "\"\"", + "targets": [ + { + "value": "1D6058900D05DD3D006BFB54", + "comment": "KitchenSinktablet" + }, + { + "value": "1D6058900D05DD3D006BFB55", + "comment": "TestApp" + } + ] + }, + "29B97313FDCFA39411CA2CEA_comment": "Project object" + }, + "PBXReferenceProxy": { + "301BF535109A57CC0062928A": { + "isa": "PBXReferenceProxy", + "fileType": "archive.ar", + "path": "libPhoneGap.a", + "remoteRef": "301BF534109A57CC0062928A", + "remoteRef_comment": "PBXContainerItemProxy", + "sourceTree": "BUILT_PRODUCTS_DIR" + }, + "301BF535109A57CC0062928A_comment": "libPhoneGap.a", + "30E47BC3136F595F00DBB853": { + "isa": "PBXReferenceProxy", + "fileType": "wrapper.cfbundle", + "path": "PhoneGap.framework", + "remoteRef": "30E47BC2136F595F00DBB853", + "remoteRef_comment": "PBXContainerItemProxy", + "sourceTree": "BUILT_PRODUCTS_DIR" + }, + "30E47BC3136F595F00DBB853_comment": "PhoneGap.framework" + }, + "PBXResourcesBuildPhase": { + "1D60588D0D05DD3D006BFB54": { + "isa": "PBXResourcesBuildPhase", + "buildActionMask": 2147483647, + "files": [ + { + "value": "301BF570109A69640062928A", + "comment": "www in Resources" + }, + { + "value": "3053AC6F109B7857006FCFE7", + "comment": "VERSION in Resources" + }, + { + "value": "30E1352710E2C1420031B30D", + "comment": "PhoneGap.plist in Resources" + }, + { + "value": "307D28A2123043360040C0FA", + "comment": "PhoneGapBuildSettings.xcconfig in Resources" + }, + { + "value": "308D05371370CCF300D202BF", + "comment": "icon-72.png in Resources" + }, + { + "value": "308D05381370CCF300D202BF", + "comment": "icon.png in Resources" + }, + { + "value": "308D05391370CCF300D202BF", + "comment": "icon@2x.png in Resources" + }, + { + "value": "308D053C1370CCF300D202BF", + "comment": "Default.png in Resources" + }, + { + "value": "308D053D1370CCF300D202BF", + "comment": "Default@2x.png in Resources" + }, + { + "value": "3072F99713A8081B00425683", + "comment": "Capture.bundle in Resources" + }, + { + "value": "1F766FE113BBADB100FB74C0", + "comment": "Localizable.strings in Resources" + }, + { + "value": "1F766FE213BBADB100FB74C0", + "comment": "Localizable.strings in Resources" + } + ], + "runOnlyForDeploymentPostprocessing": 0 + }, + "1D60588D0D05DD3D006BFB54_comment": "Resources" + }, + "PBXShellScriptBuildPhase": { + "304B58A110DAC018002A0835": { + "isa": "PBXShellScriptBuildPhase", + "buildActionMask": 2147483647, + "files": [], + "inputPaths": [], + "name": "\"Touch www folder\"", + "outputPaths": [], + "runOnlyForDeploymentPostprocessing": 0, + "shellPath": "/bin/sh", + "shellScript": "\"touch -cm ${PROJECT_DIR}/www\"" + }, + "304B58A110DAC018002A0835_comment": "Touch www folder" + }, + "PBXSourcesBuildPhase": { + "1D60588E0D05DD3D006BFB54": { + "isa": "PBXSourcesBuildPhase", + "buildActionMask": 2147483647, + "files": [ + { + "value": "1D60589B0D05DD56006BFB54", + "comment": "main.m in Sources" + }, + { + "value": "1D3623260D0F684500981E51", + "comment": "AppDelegate.m in Sources" + } + ], + "runOnlyForDeploymentPostprocessing": 0 + }, + "1D60588E0D05DD3D006BFB54_comment": "Sources" + }, + "PBXTargetDependency": { + "301BF551109A68C00062928A": { + "isa": "PBXTargetDependency", + "name": "PhoneGapLib", + "targetProxy": "301BF550109A68C00062928A", + "targetProxy_comment": "PBXContainerItemProxy" + }, + "301BF551109A68C00062928A_comment": "PBXTargetDependency" + }, + "PBXVariantGroup": { + "1F766FDC13BBADB100FB74C0": { + "isa": "PBXVariantGroup", + "children": [ + { + "value": "1F766FDD13BBADB100FB74C0", + "comment": "en" + } + ], + "name": "Localizable.strings", + "sourceTree": "\"\"" + }, + "1F766FDC13BBADB100FB74C0_comment": "Localizable.strings", + "1F766FDF13BBADB100FB74C0": { + "isa": "PBXVariantGroup", + "children": [ + { + "value": "1F766FE013BBADB100FB74C0", + "comment": "es" + } + ], + "name": "Localizable.strings", + "sourceTree": "\"\"" + }, + "1F766FDF13BBADB100FB74C0_comment": "Localizable.strings" + }, + "XCBuildConfiguration": { + "1D6058940D05DD3E006BFB54": { + "isa": "XCBuildConfiguration", + "buildSettings": { + "ALWAYS_SEARCH_USER_PATHS": "NO", + "ARCHS": [ + "armv6", + "armv7" + ], + "COPY_PHASE_STRIP": "NO", + "GCC_DYNAMIC_NO_PIC": "NO", + "GCC_OPTIMIZATION_LEVEL": 0, + "GCC_PRECOMPILE_PREFIX_HEADER": "YES", + "GCC_PREFIX_HEADER": "\"KitchenSinktablet-Prefix.pch\"", + "INFOPLIST_FILE": "\"KitchenSinktablet-Info.plist\"", + "IPHONEOS_DEPLOYMENT_TARGET": "3.0", + "ONLY_ACTIVE_ARCH": "NO", + "PRODUCT_NAME": "\"KitchenSinktablet\"", + "TARGETED_DEVICE_FAMILY": "\"1,2\"" + }, + "name": "Debug" + }, + "1D6058940D05DD3E006BFB54_comment": "Debug", + "1D6058950D05DD3E006BFB54": { + "isa": "XCBuildConfiguration", + "buildSettings": { + "ALWAYS_SEARCH_USER_PATHS": "NO", + "ARCHS": [ + "armv6", + "armv7" + ], + "COPY_PHASE_STRIP": "YES", + "GCC_PRECOMPILE_PREFIX_HEADER": "YES", + "GCC_PREFIX_HEADER": "\"KitchenSinktablet-Prefix.pch\"", + "INFOPLIST_FILE": "\"KitchenSinktablet-Info.plist\"", + "IPHONEOS_DEPLOYMENT_TARGET": "3.0", + "ONLY_ACTIVE_ARCH": "NO", + "PRODUCT_NAME": "\"KitchenSinktablet\"", + "TARGETED_DEVICE_FAMILY": "\"1,2\"" + }, + "name": "Release" + }, + "1D6058950D05DD3E006BFB54_comment": "Release", + "C01FCF4F08A954540054247B": { + "isa": "XCBuildConfiguration", + "baseConfigurationReference": "307D28A1123043350040C0FA", + "baseConfigurationReference_comment": "PhoneGapBuildSettings.xcconfig", + "buildSettings": { + "ARCHS": "\"$(ARCHS_STANDARD_32_BIT)\"", + "\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\"": "\"iPhone Distribution\"", + "GCC_C_LANGUAGE_STANDARD": "c99", + "GCC_VERSION": "com.apple.compilers.llvmgcc42", + "GCC_WARN_ABOUT_RETURN_TYPE": "YES", + "GCC_WARN_UNUSED_VARIABLE": "YES", + "IPHONEOS_DEPLOYMENT_TARGET": "3.0", + "OTHER_LDFLAGS": [ + "\"-weak_framework\"", + "UIKit", + "\"-weak_framework\"", + "AVFoundation", + "\"-weak_framework\"", + "CoreMedia", + "\"-weak_library\"", + "/usr/lib/libSystem.B.dylib", + "\"-all_load\"", + "\"-Obj-C\"" + ], + "PREBINDING": "NO", + "SDKROOT": "iphoneos", + "SKIP_INSTALL": "NO", + "USER_HEADER_SEARCH_PATHS": "\"\"$(PHONEGAPLIB)/Classes/JSON\" \"$(PHONEGAPLIB)/Classes\"\"" + }, + "name": "Debug" + }, + "C01FCF4F08A954540054247B_comment": "Debug", + "C01FCF5008A954540054247B": { + "isa": "XCBuildConfiguration", + "baseConfigurationReference": "307D28A1123043350040C0FA", + "baseConfigurationReference_comment": "PhoneGapBuildSettings.xcconfig", + "buildSettings": { + "ARCHS": "\"$(ARCHS_STANDARD_32_BIT)\"", + "\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\"": "\"iPhone Distribution\"", + "GCC_C_LANGUAGE_STANDARD": "c99", + "GCC_VERSION": "com.apple.compilers.llvmgcc42", + "GCC_WARN_ABOUT_RETURN_TYPE": "YES", + "GCC_WARN_UNUSED_VARIABLE": "YES", + "IPHONEOS_DEPLOYMENT_TARGET": "3.0", + "OTHER_LDFLAGS": [ + "\"-weak_framework\"", + "UIKit", + "\"-weak_framework\"", + "AVFoundation", + "\"-weak_framework\"", + "CoreMedia", + "\"-weak_library\"", + "/usr/lib/libSystem.B.dylib", + "\"-all_load\"", + "\"-Obj-C\"" + ], + "PREBINDING": "NO", + "SDKROOT": "iphoneos", + "SKIP_INSTALL": "NO", + "USER_HEADER_SEARCH_PATHS": "\"\"$(PHONEGAPLIB)/Classes/JSON\" \"$(PHONEGAPLIB)/Classes\"\"" + }, + "name": "Release" + }, + "C01FCF5008A954540054247B_comment": "Release" + }, + "XCConfigurationList": { + "1D6058960D05DD3E006BFB54": { + "isa": "XCConfigurationList", + "buildConfigurations": [ + { + "value": "1D6058940D05DD3E006BFB54", + "comment": "Debug" + }, + { + "value": "1D6058950D05DD3E006BFB54", + "comment": "Release" + } + ], + "defaultConfigurationIsVisible": 0, + "defaultConfigurationName": "Release" + }, + "1D6058960D05DD3E006BFB54_comment": "Build configuration list for PBXNativeTarget \"KitchenSinktablet\"", + "C01FCF4E08A954540054247B": { + "isa": "XCConfigurationList", + "buildConfigurations": [ + { + "value": "C01FCF4F08A954540054247B", + "comment": "Debug" + }, + { + "value": "C01FCF5008A954540054247B", + "comment": "Release" + } + ], + "defaultConfigurationIsVisible": 0, + "defaultConfigurationName": "Release" + }, + "C01FCF4E08A954540054247B_comment": "Build configuration list for PBXProject \"KitchenSinktablet\"" + } + }, + "rootObject": "29B97313FDCFA39411CA2CEA", + "rootObject_comment": "Project object" + }, + "headComment": "!$*UTF8*$!" +} diff --git a/test/fixtures/library-search-paths.json b/test/fixtures/library-search-paths.json new file mode 100644 index 0000000..4cddc61 --- /dev/null +++ b/test/fixtures/library-search-paths.json @@ -0,0 +1 @@ +{"project":{"archiveVersion":1,"classes":{},"objectVersion":46,"objects":{"PBXBuildFile":{"B9E76573180BDDA800888C06":{"isa":"PBXBuildFile","fileRef":"B9E76572180BDDA800888C06","fileRef_comment":"Foundation.framework"},"B9E76573180BDDA800888C06_comment":"Foundation.framework in Frameworks","B9E76575180BDDA800888C06":{"isa":"PBXBuildFile","fileRef":"B9E76574180BDDA800888C06","fileRef_comment":"CoreGraphics.framework"},"B9E76575180BDDA800888C06_comment":"CoreGraphics.framework in Frameworks","B9E76577180BDDA800888C06":{"isa":"PBXBuildFile","fileRef":"B9E76576180BDDA800888C06","fileRef_comment":"UIKit.framework"},"B9E76577180BDDA800888C06_comment":"UIKit.framework in Frameworks","B9E7657D180BDDA800888C06":{"isa":"PBXBuildFile","fileRef":"B9E7657B180BDDA800888C06","fileRef_comment":"InfoPlist.strings"},"B9E7657D180BDDA800888C06_comment":"InfoPlist.strings in Resources","B9E7657F180BDDA800888C06":{"isa":"PBXBuildFile","fileRef":"B9E7657E180BDDA800888C06","fileRef_comment":"main.m"},"B9E7657F180BDDA800888C06_comment":"main.m in Sources","B9E76583180BDDA800888C06":{"isa":"PBXBuildFile","fileRef":"B9E76582180BDDA800888C06","fileRef_comment":"AppDelegate.m"},"B9E76583180BDDA800888C06_comment":"AppDelegate.m in Sources","B9E76586180BDDA800888C06":{"isa":"PBXBuildFile","fileRef":"B9E76584180BDDA800888C06","fileRef_comment":"Main_iPhone.storyboard"},"B9E76586180BDDA800888C06_comment":"Main_iPhone.storyboard in Resources","B9E76589180BDDA800888C06":{"isa":"PBXBuildFile","fileRef":"B9E76587180BDDA800888C06","fileRef_comment":"Main_iPad.storyboard"},"B9E76589180BDDA800888C06_comment":"Main_iPad.storyboard in Resources","B9E7658C180BDDA800888C06":{"isa":"PBXBuildFile","fileRef":"B9E7658B180BDDA800888C06","fileRef_comment":"MasterViewController.m"},"B9E7658C180BDDA800888C06_comment":"MasterViewController.m in Sources","B9E7658F180BDDA800888C06":{"isa":"PBXBuildFile","fileRef":"B9E7658E180BDDA800888C06","fileRef_comment":"DetailViewController.m"},"B9E7658F180BDDA800888C06_comment":"DetailViewController.m in Sources","B9E76591180BDDA800888C06":{"isa":"PBXBuildFile","fileRef":"B9E76590180BDDA800888C06","fileRef_comment":"Images.xcassets"},"B9E76591180BDDA800888C06_comment":"Images.xcassets in Resources","B9E76598180BDDA800888C06":{"isa":"PBXBuildFile","fileRef":"B9E76597180BDDA800888C06","fileRef_comment":"XCTest.framework"},"B9E76598180BDDA800888C06_comment":"XCTest.framework in Frameworks","B9E76599180BDDA800888C06":{"isa":"PBXBuildFile","fileRef":"B9E76572180BDDA800888C06","fileRef_comment":"Foundation.framework"},"B9E76599180BDDA800888C06_comment":"Foundation.framework in Frameworks","B9E7659A180BDDA800888C06":{"isa":"PBXBuildFile","fileRef":"B9E76576180BDDA800888C06","fileRef_comment":"UIKit.framework"},"B9E7659A180BDDA800888C06_comment":"UIKit.framework in Frameworks","B9E765A2180BDDA800888C06":{"isa":"PBXBuildFile","fileRef":"B9E765A0180BDDA800888C06","fileRef_comment":"InfoPlist.strings"},"B9E765A2180BDDA800888C06_comment":"InfoPlist.strings in Resources","B9E765A4180BDDA800888C06":{"isa":"PBXBuildFile","fileRef":"B9E765A3180BDDA800888C06","fileRef_comment":"testTests.m"},"B9E765A4180BDDA800888C06_comment":"testTests.m in Sources"},"PBXContainerItemProxy":{"B9E7659B180BDDA800888C06":{"isa":"PBXContainerItemProxy","containerPortal":"B9E76567180BDDA800888C06","containerPortal_comment":"Project object","proxyType":1,"remoteGlobalIDString":"B9E7656E180BDDA800888C06","remoteInfo":"test"},"B9E7659B180BDDA800888C06_comment":"PBXContainerItemProxy"},"PBXFileReference":{"B9E7656F180BDDA800888C06":{"isa":"PBXFileReference","explicitFileType":"wrapper.application","includeInIndex":0,"path":"test.app","sourceTree":"BUILT_PRODUCTS_DIR"},"B9E7656F180BDDA800888C06_comment":"test.app","B9E76572180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"Foundation.framework","path":"System/Library/Frameworks/Foundation.framework","sourceTree":"SDKROOT"},"B9E76572180BDDA800888C06_comment":"Foundation.framework","B9E76574180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"CoreGraphics.framework","path":"System/Library/Frameworks/CoreGraphics.framework","sourceTree":"SDKROOT"},"B9E76574180BDDA800888C06_comment":"CoreGraphics.framework","B9E76576180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"UIKit.framework","path":"System/Library/Frameworks/UIKit.framework","sourceTree":"SDKROOT"},"B9E76576180BDDA800888C06_comment":"UIKit.framework","B9E7657A180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"text.plist.xml","path":"\"test-Info.plist\"","sourceTree":"\"\""},"B9E7657A180BDDA800888C06_comment":"test-Info.plist","B9E7657C180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"text.plist.strings","name":"en","path":"en.lproj/InfoPlist.strings","sourceTree":"\"\""},"B9E7657C180BDDA800888C06_comment":"en","B9E7657E180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"sourcecode.c.objc","path":"main.m","sourceTree":"\"\""},"B9E7657E180BDDA800888C06_comment":"main.m","B9E76580180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"sourcecode.c.h","path":"\"test-Prefix.pch\"","sourceTree":"\"\""},"B9E76580180BDDA800888C06_comment":"test-Prefix.pch","B9E76581180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"sourcecode.c.h","path":"AppDelegate.h","sourceTree":"\"\""},"B9E76581180BDDA800888C06_comment":"AppDelegate.h","B9E76582180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"sourcecode.c.objc","path":"AppDelegate.m","sourceTree":"\"\""},"B9E76582180BDDA800888C06_comment":"AppDelegate.m","B9E76585180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"file.storyboard","name":"Base","path":"Base.lproj/Main_iPhone.storyboard","sourceTree":"\"\""},"B9E76585180BDDA800888C06_comment":"Base","B9E76588180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"file.storyboard","name":"Base","path":"Base.lproj/Main_iPad.storyboard","sourceTree":"\"\""},"B9E76588180BDDA800888C06_comment":"Base","B9E7658A180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"sourcecode.c.h","path":"MasterViewController.h","sourceTree":"\"\""},"B9E7658A180BDDA800888C06_comment":"MasterViewController.h","B9E7658B180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"sourcecode.c.objc","path":"MasterViewController.m","sourceTree":"\"\""},"B9E7658B180BDDA800888C06_comment":"MasterViewController.m","B9E7658D180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"sourcecode.c.h","path":"DetailViewController.h","sourceTree":"\"\""},"B9E7658D180BDDA800888C06_comment":"DetailViewController.h","B9E7658E180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"sourcecode.c.objc","path":"DetailViewController.m","sourceTree":"\"\""},"B9E7658E180BDDA800888C06_comment":"DetailViewController.m","B9E76590180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"folder.assetcatalog","path":"Images.xcassets","sourceTree":"\"\""},"B9E76590180BDDA800888C06_comment":"Images.xcassets","B9E76596180BDDA800888C06":{"isa":"PBXFileReference","explicitFileType":"wrapper.cfbundle","includeInIndex":0,"path":"testTests.xctest","sourceTree":"BUILT_PRODUCTS_DIR"},"B9E76596180BDDA800888C06_comment":"testTests.xctest","B9E76597180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"XCTest.framework","path":"Library/Frameworks/XCTest.framework","sourceTree":"DEVELOPER_DIR"},"B9E76597180BDDA800888C06_comment":"XCTest.framework","B9E7659F180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"text.plist.xml","path":"\"testTests-Info.plist\"","sourceTree":"\"\""},"B9E7659F180BDDA800888C06_comment":"testTests-Info.plist","B9E765A1180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"text.plist.strings","name":"en","path":"en.lproj/InfoPlist.strings","sourceTree":"\"\""},"B9E765A1180BDDA800888C06_comment":"en","B9E765A3180BDDA800888C06":{"isa":"PBXFileReference","lastKnownFileType":"sourcecode.c.objc","path":"testTests.m","sourceTree":"\"\""},"B9E765A3180BDDA800888C06_comment":"testTests.m"},"PBXFrameworksBuildPhase":{"B9E7656C180BDDA800888C06":{"isa":"PBXFrameworksBuildPhase","buildActionMask":2147483647,"files":[{"value":"B9E76575180BDDA800888C06","comment":"CoreGraphics.framework in Frameworks"},{"value":"B9E76577180BDDA800888C06","comment":"UIKit.framework in Frameworks"},{"value":"B9E76573180BDDA800888C06","comment":"Foundation.framework in Frameworks"}],"runOnlyForDeploymentPostprocessing":0},"B9E7656C180BDDA800888C06_comment":"Frameworks","B9E76593180BDDA800888C06":{"isa":"PBXFrameworksBuildPhase","buildActionMask":2147483647,"files":[{"value":"B9E76598180BDDA800888C06","comment":"XCTest.framework in Frameworks"},{"value":"B9E7659A180BDDA800888C06","comment":"UIKit.framework in Frameworks"},{"value":"B9E76599180BDDA800888C06","comment":"Foundation.framework in Frameworks"}],"runOnlyForDeploymentPostprocessing":0},"B9E76593180BDDA800888C06_comment":"Frameworks"},"PBXGroup":{"B9E76566180BDDA800888C06":{"isa":"PBXGroup","children":[{"value":"B9E76578180BDDA800888C06","comment":"test"},{"value":"B9E7659D180BDDA800888C06","comment":"testTests"},{"value":"B9E76571180BDDA800888C06","comment":"Frameworks"},{"value":"B9E76570180BDDA800888C06","comment":"Products"}],"sourceTree":"\"\""},"B9E76570180BDDA800888C06":{"isa":"PBXGroup","children":[{"value":"B9E7656F180BDDA800888C06","comment":"test.app"},{"value":"B9E76596180BDDA800888C06","comment":"testTests.xctest"}],"name":"Products","sourceTree":"\"\""},"B9E76570180BDDA800888C06_comment":"Products","B9E76571180BDDA800888C06":{"isa":"PBXGroup","children":[{"value":"B9E76572180BDDA800888C06","comment":"Foundation.framework"},{"value":"B9E76574180BDDA800888C06","comment":"CoreGraphics.framework"},{"value":"B9E76576180BDDA800888C06","comment":"UIKit.framework"},{"value":"B9E76597180BDDA800888C06","comment":"XCTest.framework"}],"name":"Frameworks","sourceTree":"\"\""},"B9E76571180BDDA800888C06_comment":"Frameworks","B9E76578180BDDA800888C06":{"isa":"PBXGroup","children":[{"value":"B9E76581180BDDA800888C06","comment":"AppDelegate.h"},{"value":"B9E76582180BDDA800888C06","comment":"AppDelegate.m"},{"value":"B9E76584180BDDA800888C06","comment":"Main_iPhone.storyboard"},{"value":"B9E76587180BDDA800888C06","comment":"Main_iPad.storyboard"},{"value":"B9E7658A180BDDA800888C06","comment":"MasterViewController.h"},{"value":"B9E7658B180BDDA800888C06","comment":"MasterViewController.m"},{"value":"B9E7658D180BDDA800888C06","comment":"DetailViewController.h"},{"value":"B9E7658E180BDDA800888C06","comment":"DetailViewController.m"},{"value":"B9E76590180BDDA800888C06","comment":"Images.xcassets"},{"value":"B9E76579180BDDA800888C06","comment":"Supporting Files"}],"path":"test","sourceTree":"\"\""},"B9E76578180BDDA800888C06_comment":"test","B9E76579180BDDA800888C06":{"isa":"PBXGroup","children":[{"value":"B9E7657A180BDDA800888C06","comment":"test-Info.plist"},{"value":"B9E7657B180BDDA800888C06","comment":"InfoPlist.strings"},{"value":"B9E7657E180BDDA800888C06","comment":"main.m"},{"value":"B9E76580180BDDA800888C06","comment":"test-Prefix.pch"}],"name":"\"Supporting Files\"","sourceTree":"\"\""},"B9E76579180BDDA800888C06_comment":"Supporting Files","B9E7659D180BDDA800888C06":{"isa":"PBXGroup","children":[{"value":"B9E765A3180BDDA800888C06","comment":"testTests.m"},{"value":"B9E7659E180BDDA800888C06","comment":"Supporting Files"}],"path":"testTests","sourceTree":"\"\""},"B9E7659D180BDDA800888C06_comment":"testTests","B9E7659E180BDDA800888C06":{"isa":"PBXGroup","children":[{"value":"B9E7659F180BDDA800888C06","comment":"testTests-Info.plist"},{"value":"B9E765A0180BDDA800888C06","comment":"InfoPlist.strings"}],"name":"\"Supporting Files\"","sourceTree":"\"\""},"B9E7659E180BDDA800888C06_comment":"Supporting Files"},"PBXNativeTarget":{"B9E7656E180BDDA800888C06":{"isa":"PBXNativeTarget","buildConfigurationList":"B9E765A7180BDDA800888C06","buildConfigurationList_comment":"Build configuration list for PBXNativeTarget \"test\"","buildPhases":[{"value":"B9E7656B180BDDA800888C06","comment":"Sources"},{"value":"B9E7656C180BDDA800888C06","comment":"Frameworks"},{"value":"B9E7656D180BDDA800888C06","comment":"Resources"}],"buildRules":[],"dependencies":[],"name":"test","productName":"test","productReference":"B9E7656F180BDDA800888C06","productReference_comment":"test.app","productType":"\"com.apple.product-type.application\""},"B9E7656E180BDDA800888C06_comment":"test","B9E76595180BDDA800888C06":{"isa":"PBXNativeTarget","buildConfigurationList":"B9E765AA180BDDA800888C06","buildConfigurationList_comment":"Build configuration list for PBXNativeTarget \"testTests\"","buildPhases":[{"value":"B9E76592180BDDA800888C06","comment":"Sources"},{"value":"B9E76593180BDDA800888C06","comment":"Frameworks"},{"value":"B9E76594180BDDA800888C06","comment":"Resources"}],"buildRules":[],"dependencies":[{"value":"B9E7659C180BDDA800888C06","comment":"PBXTargetDependency"}],"name":"testTests","productName":"testTests","productReference":"B9E76596180BDDA800888C06","productReference_comment":"testTests.xctest","productType":"\"com.apple.product-type.bundle.unit-test\""},"B9E76595180BDDA800888C06_comment":"testTests"},"PBXProject":{"B9E76567180BDDA800888C06":{"isa":"PBXProject","attributes":{"LastUpgradeCheck":500,"ORGANIZATIONNAME":"Cordova","TargetAttributes":{"B9E76595180BDDA800888C06":{"TestTargetID":"B9E7656E180BDDA800888C06"}}},"buildConfigurationList":"B9E7656A180BDDA800888C06","buildConfigurationList_comment":"Build configuration list for PBXProject \"test\"","compatibilityVersion":"\"Xcode 3.2\"","developmentRegion":"English","hasScannedForEncodings":0,"knownRegions":["en","Base"],"mainGroup":"B9E76566180BDDA800888C06","productRefGroup":"B9E76570180BDDA800888C06","productRefGroup_comment":"Products","projectDirPath":"\"\"","projectRoot":"\"\"","targets":[{"value":"B9E7656E180BDDA800888C06","comment":"test"},{"value":"B9E76595180BDDA800888C06","comment":"testTests"}]},"B9E76567180BDDA800888C06_comment":"Project object"},"PBXResourcesBuildPhase":{"B9E7656D180BDDA800888C06":{"isa":"PBXResourcesBuildPhase","buildActionMask":2147483647,"files":[{"value":"B9E76589180BDDA800888C06","comment":"Main_iPad.storyboard in Resources"},{"value":"B9E76591180BDDA800888C06","comment":"Images.xcassets in Resources"},{"value":"B9E76586180BDDA800888C06","comment":"Main_iPhone.storyboard in Resources"},{"value":"B9E7657D180BDDA800888C06","comment":"InfoPlist.strings in Resources"}],"runOnlyForDeploymentPostprocessing":0},"B9E7656D180BDDA800888C06_comment":"Resources","B9E76594180BDDA800888C06":{"isa":"PBXResourcesBuildPhase","buildActionMask":2147483647,"files":[{"value":"B9E765A2180BDDA800888C06","comment":"InfoPlist.strings in Resources"}],"runOnlyForDeploymentPostprocessing":0},"B9E76594180BDDA800888C06_comment":"Resources"},"PBXSourcesBuildPhase":{"B9E7656B180BDDA800888C06":{"isa":"PBXSourcesBuildPhase","buildActionMask":2147483647,"files":[{"value":"B9E76583180BDDA800888C06","comment":"AppDelegate.m in Sources"},{"value":"B9E7658C180BDDA800888C06","comment":"MasterViewController.m in Sources"},{"value":"B9E7657F180BDDA800888C06","comment":"main.m in Sources"},{"value":"B9E7658F180BDDA800888C06","comment":"DetailViewController.m in Sources"}],"runOnlyForDeploymentPostprocessing":0},"B9E7656B180BDDA800888C06_comment":"Sources","B9E76592180BDDA800888C06":{"isa":"PBXSourcesBuildPhase","buildActionMask":2147483647,"files":[{"value":"B9E765A4180BDDA800888C06","comment":"testTests.m in Sources"}],"runOnlyForDeploymentPostprocessing":0},"B9E76592180BDDA800888C06_comment":"Sources"},"PBXTargetDependency":{"B9E7659C180BDDA800888C06":{"isa":"PBXTargetDependency","target":"B9E7656E180BDDA800888C06","target_comment":"test","targetProxy":"B9E7659B180BDDA800888C06","targetProxy_comment":"PBXContainerItemProxy"},"B9E7659C180BDDA800888C06_comment":"PBXTargetDependency"},"PBXVariantGroup":{"B9E7657B180BDDA800888C06":{"isa":"PBXVariantGroup","children":[{"value":"B9E7657C180BDDA800888C06","comment":"en"}],"name":"InfoPlist.strings","sourceTree":"\"\""},"B9E7657B180BDDA800888C06_comment":"InfoPlist.strings","B9E76584180BDDA800888C06":{"isa":"PBXVariantGroup","children":[{"value":"B9E76585180BDDA800888C06","comment":"Base"}],"name":"Main_iPhone.storyboard","sourceTree":"\"\""},"B9E76584180BDDA800888C06_comment":"Main_iPhone.storyboard","B9E76587180BDDA800888C06":{"isa":"PBXVariantGroup","children":[{"value":"B9E76588180BDDA800888C06","comment":"Base"}],"name":"Main_iPad.storyboard","sourceTree":"\"\""},"B9E76587180BDDA800888C06_comment":"Main_iPad.storyboard","B9E765A0180BDDA800888C06":{"isa":"PBXVariantGroup","children":[{"value":"B9E765A1180BDDA800888C06","comment":"en"}],"name":"InfoPlist.strings","sourceTree":"\"\""},"B9E765A0180BDDA800888C06_comment":"InfoPlist.strings"},"XCBuildConfiguration":{"B9E765A5180BDDA800888C06":{"isa":"XCBuildConfiguration","buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","ARCHS":"\"$(ARCHS_STANDARD_INCLUDING_64_BIT)\"","CLANG_CXX_LANGUAGE_STANDARD":"\"gnu++0x\"","CLANG_CXX_LIBRARY":"\"libc++\"","CLANG_ENABLE_MODULES":"YES","CLANG_ENABLE_OBJC_ARC":"YES","CLANG_WARN_BOOL_CONVERSION":"YES","CLANG_WARN_CONSTANT_CONVERSION":"YES","CLANG_WARN_DIRECT_OBJC_ISA_USAGE":"YES_ERROR","CLANG_WARN_EMPTY_BODY":"YES","CLANG_WARN_ENUM_CONVERSION":"YES","CLANG_WARN_INT_CONVERSION":"YES","CLANG_WARN_OBJC_ROOT_CLASS":"YES_ERROR","CLANG_WARN__DUPLICATE_METHOD_MATCH":"YES","\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\"":"\"iPhone Developer\"","COPY_PHASE_STRIP":"NO","GCC_C_LANGUAGE_STANDARD":"gnu99","GCC_DYNAMIC_NO_PIC":"NO","GCC_OPTIMIZATION_LEVEL":0,"GCC_PREPROCESSOR_DEFINITIONS":["\"DEBUG=1\"","\"$(inherited)\""],"GCC_SYMBOLS_PRIVATE_EXTERN":"NO","GCC_WARN_64_TO_32_BIT_CONVERSION":"YES","GCC_WARN_ABOUT_RETURN_TYPE":"YES_ERROR","GCC_WARN_UNDECLARED_SELECTOR":"YES","GCC_WARN_UNINITIALIZED_AUTOS":"YES","GCC_WARN_UNUSED_FUNCTION":"YES","GCC_WARN_UNUSED_VARIABLE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"7.0","LIBRARY_SEARCH_PATHS":"\"$(inherited)\"","ONLY_ACTIVE_ARCH":"YES","SDKROOT":"iphoneos","TARGETED_DEVICE_FAMILY":"\"1,2\""},"name":"Debug"},"B9E765A5180BDDA800888C06_comment":"Debug","B9E765A6180BDDA800888C06":{"isa":"XCBuildConfiguration","buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","ARCHS":"\"$(ARCHS_STANDARD_INCLUDING_64_BIT)\"","CLANG_CXX_LANGUAGE_STANDARD":"\"gnu++0x\"","CLANG_CXX_LIBRARY":"\"libc++\"","CLANG_ENABLE_MODULES":"YES","CLANG_ENABLE_OBJC_ARC":"YES","CLANG_WARN_BOOL_CONVERSION":"YES","CLANG_WARN_CONSTANT_CONVERSION":"YES","CLANG_WARN_DIRECT_OBJC_ISA_USAGE":"YES_ERROR","CLANG_WARN_EMPTY_BODY":"YES","CLANG_WARN_ENUM_CONVERSION":"YES","CLANG_WARN_INT_CONVERSION":"YES","CLANG_WARN_OBJC_ROOT_CLASS":"YES_ERROR","CLANG_WARN__DUPLICATE_METHOD_MATCH":"YES","\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\"":"\"iPhone Developer\"","COPY_PHASE_STRIP":"YES","ENABLE_NS_ASSERTIONS":"NO","GCC_C_LANGUAGE_STANDARD":"gnu99","GCC_WARN_64_TO_32_BIT_CONVERSION":"YES","GCC_WARN_ABOUT_RETURN_TYPE":"YES_ERROR","GCC_WARN_UNDECLARED_SELECTOR":"YES","GCC_WARN_UNINITIALIZED_AUTOS":"YES","GCC_WARN_UNUSED_FUNCTION":"YES","GCC_WARN_UNUSED_VARIABLE":"YES","IPHONEOS_DEPLOYMENT_TARGET":"7.0","LIBRARY_SEARCH_PATHS":"\"$(inherited)\"","SDKROOT":"iphoneos","TARGETED_DEVICE_FAMILY":"\"1,2\"","VALIDATE_PRODUCT":"YES"},"name":"Release"},"B9E765A6180BDDA800888C06_comment":"Release","B9E765A8180BDDA800888C06":{"isa":"XCBuildConfiguration","buildSettings":{"ASSETCATALOG_COMPILER_APPICON_NAME":"AppIcon","ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME":"LaunchImage","GCC_PRECOMPILE_PREFIX_HEADER":"YES","GCC_PREFIX_HEADER":"\"test/test-Prefix.pch\"","INFOPLIST_FILE":"\"test/test-Info.plist\"","LIBRARY_SEARCH_PATHS":"\"$(inherited)\"","PRODUCT_NAME":"\"$(TARGET_NAME)\"","WRAPPER_EXTENSION":"app"},"name":"Debug"},"B9E765A8180BDDA800888C06_comment":"Debug","B9E765A9180BDDA800888C06":{"isa":"XCBuildConfiguration","buildSettings":{"ASSETCATALOG_COMPILER_APPICON_NAME":"AppIcon","ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME":"LaunchImage","GCC_PRECOMPILE_PREFIX_HEADER":"YES","GCC_PREFIX_HEADER":"\"test/test-Prefix.pch\"","INFOPLIST_FILE":"\"test/test-Info.plist\"","LIBRARY_SEARCH_PATHS":"\"$(inherited)\"","PRODUCT_NAME":"\"$(TARGET_NAME)\"","WRAPPER_EXTENSION":"app"},"name":"Release"},"B9E765A9180BDDA800888C06_comment":"Release","B9E765AB180BDDA800888C06":{"isa":"XCBuildConfiguration","buildSettings":{"ARCHS":"\"$(ARCHS_STANDARD_INCLUDING_64_BIT)\"","BUNDLE_LOADER":"\"$(BUILT_PRODUCTS_DIR)/test.app/test\"","FRAMEWORK_SEARCH_PATHS":["\"$(SDKROOT)/Developer/Library/Frameworks\"","\"$(inherited)\"","\"$(DEVELOPER_FRAMEWORKS_DIR)\""],"GCC_PRECOMPILE_PREFIX_HEADER":"YES","GCC_PREFIX_HEADER":"\"test/test-Prefix.pch\"","GCC_PREPROCESSOR_DEFINITIONS":["\"DEBUG=1\"","\"$(inherited)\""],"INFOPLIST_FILE":"\"testTests/testTests-Info.plist\"","PRODUCT_NAME":"\"$(TARGET_NAME)\"","TEST_HOST":"\"$(BUNDLE_LOADER)\"","WRAPPER_EXTENSION":"xctest"},"name":"Debug"},"B9E765AB180BDDA800888C06_comment":"Debug","B9E765AC180BDDA800888C06":{"isa":"XCBuildConfiguration","buildSettings":{"ARCHS":"\"$(ARCHS_STANDARD_INCLUDING_64_BIT)\"","BUNDLE_LOADER":"\"$(BUILT_PRODUCTS_DIR)/test.app/test\"","FRAMEWORK_SEARCH_PATHS":["\"$(SDKROOT)/Developer/Library/Frameworks\"","\"$(inherited)\"","\"$(DEVELOPER_FRAMEWORKS_DIR)\""],"GCC_PRECOMPILE_PREFIX_HEADER":"YES","GCC_PREFIX_HEADER":"\"test/test-Prefix.pch\"","INFOPLIST_FILE":"\"testTests/testTests-Info.plist\"","PRODUCT_NAME":"\"$(TARGET_NAME)\"","TEST_HOST":"\"$(BUNDLE_LOADER)\"","WRAPPER_EXTENSION":"xctest"},"name":"Release"},"B9E765AC180BDDA800888C06_comment":"Release"},"XCConfigurationList":{"B9E7656A180BDDA800888C06":{"isa":"XCConfigurationList","buildConfigurations":[{"value":"B9E765A5180BDDA800888C06","comment":"Debug"},{"value":"B9E765A6180BDDA800888C06","comment":"Release"}],"defaultConfigurationIsVisible":0,"defaultConfigurationName":"Release"},"B9E7656A180BDDA800888C06_comment":"Build configuration list for PBXProject \"test\"","B9E765A7180BDDA800888C06":{"isa":"XCConfigurationList","buildConfigurations":[{"value":"B9E765A8180BDDA800888C06","comment":"Debug"},{"value":"B9E765A9180BDDA800888C06","comment":"Release"}],"defaultConfigurationIsVisible":0},"B9E765A7180BDDA800888C06_comment":"Build configuration list for PBXNativeTarget \"test\"","B9E765AA180BDDA800888C06":{"isa":"XCConfigurationList","buildConfigurations":[{"value":"B9E765AB180BDDA800888C06","comment":"Debug"},{"value":"B9E765AC180BDDA800888C06","comment":"Release"}],"defaultConfigurationIsVisible":0},"B9E765AA180BDDA800888C06_comment":"Build configuration list for PBXNativeTarget \"testTests\""}},"rootObject":"B9E76567180BDDA800888C06","rootObject_comment":"Project object"}} diff --git a/test/fixtures/multiple-data-model.xcdatamodeld/.xccurrentversion b/test/fixtures/multiple-data-model.xcdatamodeld/.xccurrentversion new file mode 100644 index 0000000..cb72aba --- /dev/null +++ b/test/fixtures/multiple-data-model.xcdatamodeld/.xccurrentversion @@ -0,0 +1,8 @@ + + + + + _XCCurrentVersionName + 2.xcdatamodel + + diff --git a/test/fixtures/multiple-data-model.xcdatamodeld/1.xcdatamodel/contents b/test/fixtures/multiple-data-model.xcdatamodeld/1.xcdatamodel/contents new file mode 100644 index 0000000..6bd3dcd --- /dev/null +++ b/test/fixtures/multiple-data-model.xcdatamodeld/1.xcdatamodel/contents @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/test/fixtures/multiple-data-model.xcdatamodeld/2.xcdatamodel/contents b/test/fixtures/multiple-data-model.xcdatamodeld/2.xcdatamodel/contents new file mode 100644 index 0000000..6bd3dcd --- /dev/null +++ b/test/fixtures/multiple-data-model.xcdatamodeld/2.xcdatamodel/contents @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/test/fixtures/multiple-targets.json b/test/fixtures/multiple-targets.json new file mode 100644 index 0000000..f8a489c --- /dev/null +++ b/test/fixtures/multiple-targets.json @@ -0,0 +1 @@ +{"project":{"archiveVersion":1,"classes":{},"objectVersion":46,"objects":{"PBXBuildFile":{"09536AAE1B0D118800A1D6F8":{"isa":"PBXBuildFile","fileRef":"09536AAD1B0D118800A1D6F8","fileRef_comment":"InterfaceController.m"},"09536AAE1B0D118800A1D6F8_comment":"InterfaceController.m in Sources","09536AB11B0D118800A1D6F8":{"isa":"PBXBuildFile","fileRef":"09536AB01B0D118800A1D6F8","fileRef_comment":"NotificationController.m"},"09536AB11B0D118800A1D6F8_comment":"NotificationController.m in Sources","09536AB31B0D118800A1D6F8":{"isa":"PBXBuildFile","fileRef":"09536AB21B0D118800A1D6F8","fileRef_comment":"Images.xcassets"},"09536AB31B0D118800A1D6F8_comment":"Images.xcassets in Resources","09536AB71B0D118900A1D6F8":{"isa":"PBXBuildFile","fileRef":"09536AB61B0D118900A1D6F8","fileRef_comment":"HelloCordova WatchKit App.app"},"09536AB71B0D118900A1D6F8_comment":"HelloCordova WatchKit App.app in Resources","09536ABF1B0D118900A1D6F8":{"isa":"PBXBuildFile","fileRef":"09536ABD1B0D118900A1D6F8","fileRef_comment":"Interface.storyboard"},"09536ABF1B0D118900A1D6F8_comment":"Interface.storyboard in Resources","09536AC11B0D118900A1D6F8":{"isa":"PBXBuildFile","fileRef":"09536AC01B0D118900A1D6F8","fileRef_comment":"Images.xcassets"},"09536AC11B0D118900A1D6F8_comment":"Images.xcassets in Resources","09536AC41B0D118900A1D6F8":{"isa":"PBXBuildFile","fileRef":"09536AA71B0D118800A1D6F8","fileRef_comment":"HelloCordova WatchKit Extension.appex","settings":{"ATTRIBUTES":["RemoveHeadersOnCopy"]}},"09536AC41B0D118900A1D6F8_comment":"HelloCordova WatchKit Extension.appex in Embed App Extensions","1D3623260D0F684500981E51":{"isa":"PBXBuildFile","fileRef":"1D3623250D0F684500981E51","fileRef_comment":"AppDelegate.m"},"1D3623260D0F684500981E51_comment":"AppDelegate.m in Sources","1D60589B0D05DD56006BFB54":{"isa":"PBXBuildFile","fileRef":"29B97316FDCFA39411CA2CEA","fileRef_comment":"main.m"},"1D60589B0D05DD56006BFB54_comment":"main.m in Sources","288765FD0DF74451002DB57D":{"isa":"PBXBuildFile","fileRef":"288765FC0DF74451002DB57D","fileRef_comment":"CoreGraphics.framework"},"288765FD0DF74451002DB57D_comment":"CoreGraphics.framework in Frameworks","301BF552109A68D80062928A":{"isa":"PBXBuildFile","fileRef":"301BF535109A57CC0062928A","fileRef_comment":"libCordova.a"},"301BF552109A68D80062928A_comment":"libCordova.a in Frameworks","302D95F114D2391D003F00A1":{"isa":"PBXBuildFile","fileRef":"302D95EF14D2391D003F00A1","fileRef_comment":"MainViewController.m"},"302D95F114D2391D003F00A1_comment":"MainViewController.m in Sources","302D95F214D2391D003F00A1":{"isa":"PBXBuildFile","fileRef":"302D95F014D2391D003F00A1","fileRef_comment":"MainViewController.xib"},"302D95F214D2391D003F00A1_comment":"MainViewController.xib in Resources","305D5FD1115AB8F900A74A75":{"isa":"PBXBuildFile","fileRef":"305D5FD0115AB8F900A74A75","fileRef_comment":"MobileCoreServices.framework"},"305D5FD1115AB8F900A74A75_comment":"MobileCoreServices.framework in Frameworks","3088BBBD154F3926009F9C59":{"isa":"PBXBuildFile","fileRef":"3088BBB7154F3926009F9C59","fileRef_comment":"Default-Landscape@2x~ipad.png"},"3088BBBD154F3926009F9C59_comment":"Default-Landscape@2x~ipad.png in Resources","3088BBBE154F3926009F9C59":{"isa":"PBXBuildFile","fileRef":"3088BBB8154F3926009F9C59","fileRef_comment":"Default-Landscape~ipad.png"},"3088BBBE154F3926009F9C59_comment":"Default-Landscape~ipad.png in Resources","3088BBBF154F3926009F9C59":{"isa":"PBXBuildFile","fileRef":"3088BBB9154F3926009F9C59","fileRef_comment":"Default-Portrait@2x~ipad.png"},"3088BBBF154F3926009F9C59_comment":"Default-Portrait@2x~ipad.png in Resources","3088BBC0154F3926009F9C59":{"isa":"PBXBuildFile","fileRef":"3088BBBA154F3926009F9C59","fileRef_comment":"Default-Portrait~ipad.png"},"3088BBC0154F3926009F9C59_comment":"Default-Portrait~ipad.png in Resources","3088BBC1154F3926009F9C59":{"isa":"PBXBuildFile","fileRef":"3088BBBB154F3926009F9C59","fileRef_comment":"Default@2x~iphone.png"},"3088BBC1154F3926009F9C59_comment":"Default@2x~iphone.png in Resources","3088BBC2154F3926009F9C59":{"isa":"PBXBuildFile","fileRef":"3088BBBC154F3926009F9C59","fileRef_comment":"Default~iphone.png"},"3088BBC2154F3926009F9C59_comment":"Default~iphone.png in Resources","308D05371370CCF300D202BF":{"isa":"PBXBuildFile","fileRef":"308D052E1370CCF300D202BF","fileRef_comment":"icon-72.png"},"308D05371370CCF300D202BF_comment":"icon-72.png in Resources","308D05381370CCF300D202BF":{"isa":"PBXBuildFile","fileRef":"308D052F1370CCF300D202BF","fileRef_comment":"icon.png"},"308D05381370CCF300D202BF_comment":"icon.png in Resources","308D05391370CCF300D202BF":{"isa":"PBXBuildFile","fileRef":"308D05301370CCF300D202BF","fileRef_comment":"icon@2x.png"},"308D05391370CCF300D202BF_comment":"icon@2x.png in Resources","30B4F30019D5E07200D9F7D8":{"isa":"PBXBuildFile","fileRef":"30B4F2FD19D5E07200D9F7D8","fileRef_comment":"Default-667h.png"},"30B4F30019D5E07200D9F7D8_comment":"Default-667h.png in Resources","30B4F30119D5E07200D9F7D8":{"isa":"PBXBuildFile","fileRef":"30B4F2FE19D5E07200D9F7D8","fileRef_comment":"Default-736h.png"},"30B4F30119D5E07200D9F7D8_comment":"Default-736h.png in Resources","30B4F30219D5E07200D9F7D8":{"isa":"PBXBuildFile","fileRef":"30B4F2FF19D5E07200D9F7D8","fileRef_comment":"Default-Landscape-736h.png"},"30B4F30219D5E07200D9F7D8_comment":"Default-Landscape-736h.png in Resources","30C1856619D5FC0A00212699":{"isa":"PBXBuildFile","fileRef":"30C1856519D5FC0A00212699","fileRef_comment":"icon-60@3x.png"},"30C1856619D5FC0A00212699_comment":"icon-60@3x.png in Resources","30FC414916E50CA1004E6F35":{"isa":"PBXBuildFile","fileRef":"30FC414816E50CA1004E6F35","fileRef_comment":"icon-72@2x.png"},"30FC414916E50CA1004E6F35_comment":"icon-72@2x.png in Resources","5B1594DD16A7569C00FEF299":{"isa":"PBXBuildFile","fileRef":"5B1594DC16A7569C00FEF299","fileRef_comment":"AssetsLibrary.framework"},"5B1594DD16A7569C00FEF299_comment":"AssetsLibrary.framework in Frameworks","7E7966DE1810823500FA85AD":{"isa":"PBXBuildFile","fileRef":"7E7966D41810823500FA85AD","fileRef_comment":"icon-40.png"},"7E7966DE1810823500FA85AD_comment":"icon-40.png in Resources","7E7966DF1810823500FA85AD":{"isa":"PBXBuildFile","fileRef":"7E7966D51810823500FA85AD","fileRef_comment":"icon-40@2x.png"},"7E7966DF1810823500FA85AD_comment":"icon-40@2x.png in Resources","7E7966E01810823500FA85AD":{"isa":"PBXBuildFile","fileRef":"7E7966D61810823500FA85AD","fileRef_comment":"icon-50.png"},"7E7966E01810823500FA85AD_comment":"icon-50.png in Resources","7E7966E11810823500FA85AD":{"isa":"PBXBuildFile","fileRef":"7E7966D71810823500FA85AD","fileRef_comment":"icon-50@2x.png"},"7E7966E11810823500FA85AD_comment":"icon-50@2x.png in Resources","7E7966E21810823500FA85AD":{"isa":"PBXBuildFile","fileRef":"7E7966D81810823500FA85AD","fileRef_comment":"icon-60.png"},"7E7966E21810823500FA85AD_comment":"icon-60.png in Resources","7E7966E31810823500FA85AD":{"isa":"PBXBuildFile","fileRef":"7E7966D91810823500FA85AD","fileRef_comment":"icon-60@2x.png"},"7E7966E31810823500FA85AD_comment":"icon-60@2x.png in Resources","7E7966E41810823500FA85AD":{"isa":"PBXBuildFile","fileRef":"7E7966DA1810823500FA85AD","fileRef_comment":"icon-76.png"},"7E7966E41810823500FA85AD_comment":"icon-76.png in Resources","7E7966E51810823500FA85AD":{"isa":"PBXBuildFile","fileRef":"7E7966DB1810823500FA85AD","fileRef_comment":"icon-76@2x.png"},"7E7966E51810823500FA85AD_comment":"icon-76@2x.png in Resources","7E7966E61810823500FA85AD":{"isa":"PBXBuildFile","fileRef":"7E7966DC1810823500FA85AD","fileRef_comment":"icon-small.png"},"7E7966E61810823500FA85AD_comment":"icon-small.png in Resources","7E7966E71810823500FA85AD":{"isa":"PBXBuildFile","fileRef":"7E7966DD1810823500FA85AD","fileRef_comment":"icon-small@2x.png"},"7E7966E71810823500FA85AD_comment":"icon-small@2x.png in Resources","D4A0D8761607E02300AEF8BB":{"isa":"PBXBuildFile","fileRef":"D4A0D8751607E02300AEF8BB","fileRef_comment":"Default-568h@2x~iphone.png"},"D4A0D8761607E02300AEF8BB_comment":"Default-568h@2x~iphone.png in Resources","BA0D8677B2654B4BB7146A16":{"isa":"PBXBuildFile","fileRef":"BF861BABA0714F35A28C9CE1","fileRef_comment":"CDVLogger.m"},"BA0D8677B2654B4BB7146A16_comment":"CDVLogger.m in Sources"},"PBXContainerItemProxy":{"09536AB81B0D118900A1D6F8":{"isa":"PBXContainerItemProxy","containerPortal":"29B97313FDCFA39411CA2CEA","containerPortal_comment":"Project object","proxyType":1,"remoteGlobalIDString":"09536AB51B0D118900A1D6F8","remoteInfo":"\"HelloCordova WatchKit App\""},"09536AB81B0D118900A1D6F8_comment":"PBXContainerItemProxy","09536AC21B0D118900A1D6F8":{"isa":"PBXContainerItemProxy","containerPortal":"29B97313FDCFA39411CA2CEA","containerPortal_comment":"Project object","proxyType":1,"remoteGlobalIDString":"09536AA61B0D118800A1D6F8","remoteInfo":"\"HelloCordova WatchKit Extension\""},"09536AC21B0D118900A1D6F8_comment":"PBXContainerItemProxy","301BF534109A57CC0062928A":{"isa":"PBXContainerItemProxy","containerPortal":"301BF52D109A57CC0062928A","containerPortal_comment":"CordovaLib.xcodeproj","proxyType":2,"remoteGlobalIDString":"D2AAC07E0554694100DB518D","remoteInfo":"CordovaLib"},"301BF534109A57CC0062928A_comment":"PBXContainerItemProxy","301BF550109A68C00062928A":{"isa":"PBXContainerItemProxy","containerPortal":"301BF52D109A57CC0062928A","containerPortal_comment":"CordovaLib.xcodeproj","proxyType":1,"remoteGlobalIDString":"D2AAC07D0554694100DB518D","remoteInfo":"CordovaLib"},"301BF550109A68C00062928A_comment":"PBXContainerItemProxy"},"PBXCopyFilesBuildPhase":{"09536ACB1B0D118900A1D6F8":{"isa":"PBXCopyFilesBuildPhase","buildActionMask":2147483647,"dstPath":"\"\"","dstSubfolderSpec":13,"files":[{"value":"09536AC41B0D118900A1D6F8","comment":"HelloCordova WatchKit Extension.appex in Embed App Extensions"}],"name":"\"Embed App Extensions\"","runOnlyForDeploymentPostprocessing":0},"09536ACB1B0D118900A1D6F8_comment":"Embed App Extensions"},"PBXFileReference":{"09536AA71B0D118800A1D6F8":{"isa":"PBXFileReference","explicitFileType":"\"wrapper.app-extension\"","includeInIndex":0,"path":"\"HelloCordova WatchKit Extension.appex\"","sourceTree":"BUILT_PRODUCTS_DIR"},"09536AA71B0D118800A1D6F8_comment":"HelloCordova WatchKit Extension.appex","09536AAA1B0D118800A1D6F8":{"isa":"PBXFileReference","lastKnownFileType":"text.plist.xml","path":"Info.plist","sourceTree":"\"\""},"09536AAA1B0D118800A1D6F8_comment":"Info.plist","09536AAB1B0D118800A1D6F8":{"isa":"PBXFileReference","lastKnownFileType":"text","path":"PushNotificationPayload.apns","sourceTree":"\"\""},"09536AAB1B0D118800A1D6F8_comment":"PushNotificationPayload.apns","09536AAC1B0D118800A1D6F8":{"isa":"PBXFileReference","lastKnownFileType":"sourcecode.c.h","path":"InterfaceController.h","sourceTree":"\"\""},"09536AAC1B0D118800A1D6F8_comment":"InterfaceController.h","09536AAD1B0D118800A1D6F8":{"isa":"PBXFileReference","lastKnownFileType":"sourcecode.c.objc","path":"InterfaceController.m","sourceTree":"\"\""},"09536AAD1B0D118800A1D6F8_comment":"InterfaceController.m","09536AAF1B0D118800A1D6F8":{"isa":"PBXFileReference","lastKnownFileType":"sourcecode.c.h","path":"NotificationController.h","sourceTree":"\"\""},"09536AAF1B0D118800A1D6F8_comment":"NotificationController.h","09536AB01B0D118800A1D6F8":{"isa":"PBXFileReference","lastKnownFileType":"sourcecode.c.objc","path":"NotificationController.m","sourceTree":"\"\""},"09536AB01B0D118800A1D6F8_comment":"NotificationController.m","09536AB21B0D118800A1D6F8":{"isa":"PBXFileReference","lastKnownFileType":"folder.assetcatalog","path":"Images.xcassets","sourceTree":"\"\""},"09536AB21B0D118800A1D6F8_comment":"Images.xcassets","09536AB61B0D118900A1D6F8":{"isa":"PBXFileReference","explicitFileType":"wrapper.application","includeInIndex":0,"path":"\"HelloCordova WatchKit App.app\"","sourceTree":"BUILT_PRODUCTS_DIR"},"09536AB61B0D118900A1D6F8_comment":"HelloCordova WatchKit App.app","09536ABC1B0D118900A1D6F8":{"isa":"PBXFileReference","lastKnownFileType":"text.plist.xml","path":"Info.plist","sourceTree":"\"\""},"09536ABC1B0D118900A1D6F8_comment":"Info.plist","09536ABE1B0D118900A1D6F8":{"isa":"PBXFileReference","lastKnownFileType":"file.storyboard","name":"Base","path":"Base.lproj/Interface.storyboard","sourceTree":"\"\""},"09536ABE1B0D118900A1D6F8_comment":"Base","09536AC01B0D118900A1D6F8":{"isa":"PBXFileReference","lastKnownFileType":"folder.assetcatalog","path":"Images.xcassets","sourceTree":"\"\""},"09536AC01B0D118900A1D6F8_comment":"Images.xcassets","1D3623240D0F684500981E51":{"isa":"PBXFileReference","fileEncoding":4,"lastKnownFileType":"sourcecode.c.h","path":"AppDelegate.h","sourceTree":"\"\""},"1D3623240D0F684500981E51_comment":"AppDelegate.h","1D3623250D0F684500981E51":{"isa":"PBXFileReference","fileEncoding":4,"lastKnownFileType":"sourcecode.c.objc","path":"AppDelegate.m","sourceTree":"\"\""},"1D3623250D0F684500981E51_comment":"AppDelegate.m","1D6058910D05DD3D006BFB54":{"isa":"PBXFileReference","explicitFileType":"wrapper.application","includeInIndex":0,"path":"HelloCordova.app","sourceTree":"BUILT_PRODUCTS_DIR"},"1D6058910D05DD3D006BFB54_comment":"HelloCordova.app","288765FC0DF74451002DB57D":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"CoreGraphics.framework","path":"System/Library/Frameworks/CoreGraphics.framework","sourceTree":"SDKROOT"},"288765FC0DF74451002DB57D_comment":"CoreGraphics.framework","29B97316FDCFA39411CA2CEA":{"isa":"PBXFileReference","fileEncoding":4,"lastKnownFileType":"sourcecode.c.objc","path":"main.m","sourceTree":"\"\""},"29B97316FDCFA39411CA2CEA_comment":"main.m","301BF52D109A57CC0062928A":{"isa":"PBXFileReference","lastKnownFileType":"\"wrapper.pb-project\"","name":"CordovaLib.xcodeproj","path":"CordovaLib/CordovaLib.xcodeproj","sourceTree":"\"\""},"301BF52D109A57CC0062928A_comment":"CordovaLib.xcodeproj","301BF56E109A69640062928A":{"isa":"PBXFileReference","lastKnownFileType":"folder","path":"www","sourceTree":"SOURCE_ROOT"},"301BF56E109A69640062928A_comment":"www","302D95EE14D2391D003F00A1":{"isa":"PBXFileReference","fileEncoding":4,"lastKnownFileType":"sourcecode.c.h","path":"MainViewController.h","sourceTree":"\"\""},"302D95EE14D2391D003F00A1_comment":"MainViewController.h","302D95EF14D2391D003F00A1":{"isa":"PBXFileReference","fileEncoding":4,"lastKnownFileType":"sourcecode.c.objc","path":"MainViewController.m","sourceTree":"\"\""},"302D95EF14D2391D003F00A1_comment":"MainViewController.m","302D95F014D2391D003F00A1":{"isa":"PBXFileReference","fileEncoding":4,"lastKnownFileType":"file.xib","path":"MainViewController.xib","sourceTree":"\"\""},"302D95F014D2391D003F00A1_comment":"MainViewController.xib","305D5FD0115AB8F900A74A75":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"MobileCoreServices.framework","path":"System/Library/Frameworks/MobileCoreServices.framework","sourceTree":"SDKROOT"},"305D5FD0115AB8F900A74A75_comment":"MobileCoreServices.framework","3088BBB7154F3926009F9C59":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"Default-Landscape@2x~ipad.png\"","sourceTree":"\"\""},"3088BBB7154F3926009F9C59_comment":"Default-Landscape@2x~ipad.png","3088BBB8154F3926009F9C59":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"Default-Landscape~ipad.png\"","sourceTree":"\"\""},"3088BBB8154F3926009F9C59_comment":"Default-Landscape~ipad.png","3088BBB9154F3926009F9C59":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"Default-Portrait@2x~ipad.png\"","sourceTree":"\"\""},"3088BBB9154F3926009F9C59_comment":"Default-Portrait@2x~ipad.png","3088BBBA154F3926009F9C59":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"Default-Portrait~ipad.png\"","sourceTree":"\"\""},"3088BBBA154F3926009F9C59_comment":"Default-Portrait~ipad.png","3088BBBB154F3926009F9C59":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"Default@2x~iphone.png\"","sourceTree":"\"\""},"3088BBBB154F3926009F9C59_comment":"Default@2x~iphone.png","3088BBBC154F3926009F9C59":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"Default~iphone.png\"","sourceTree":"\"\""},"3088BBBC154F3926009F9C59_comment":"Default~iphone.png","308D052E1370CCF300D202BF":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"icon-72.png\"","sourceTree":"\"\""},"308D052E1370CCF300D202BF_comment":"icon-72.png","308D052F1370CCF300D202BF":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"icon.png","sourceTree":"\"\""},"308D052F1370CCF300D202BF_comment":"icon.png","308D05301370CCF300D202BF":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"icon@2x.png\"","sourceTree":"\"\""},"308D05301370CCF300D202BF_comment":"icon@2x.png","30B4F2FD19D5E07200D9F7D8":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"Default-667h.png\"","sourceTree":"\"\""},"30B4F2FD19D5E07200D9F7D8_comment":"Default-667h.png","30B4F2FE19D5E07200D9F7D8":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"Default-736h.png\"","sourceTree":"\"\""},"30B4F2FE19D5E07200D9F7D8_comment":"Default-736h.png","30B4F2FF19D5E07200D9F7D8":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"Default-Landscape-736h.png\"","sourceTree":"\"\""},"30B4F2FF19D5E07200D9F7D8_comment":"Default-Landscape-736h.png","30C1856519D5FC0A00212699":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"icon-60@3x.png\"","sourceTree":"\"\""},"30C1856519D5FC0A00212699_comment":"icon-60@3x.png","30FC414816E50CA1004E6F35":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"icon-72@2x.png\"","sourceTree":"\"\""},"30FC414816E50CA1004E6F35_comment":"icon-72@2x.png","32CA4F630368D1EE00C91783":{"isa":"PBXFileReference","fileEncoding":4,"lastKnownFileType":"sourcecode.c.h","path":"\"HelloCordova-Prefix.pch\"","sourceTree":"\"\""},"32CA4F630368D1EE00C91783_comment":"HelloCordova-Prefix.pch","5B1594DC16A7569C00FEF299":{"isa":"PBXFileReference","lastKnownFileType":"wrapper.framework","name":"AssetsLibrary.framework","path":"System/Library/Frameworks/AssetsLibrary.framework","sourceTree":"SDKROOT"},"5B1594DC16A7569C00FEF299_comment":"AssetsLibrary.framework","7E7966D41810823500FA85AD":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"icon-40.png\"","sourceTree":"\"\""},"7E7966D41810823500FA85AD_comment":"icon-40.png","7E7966D51810823500FA85AD":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"icon-40@2x.png\"","sourceTree":"\"\""},"7E7966D51810823500FA85AD_comment":"icon-40@2x.png","7E7966D61810823500FA85AD":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"icon-50.png\"","sourceTree":"\"\""},"7E7966D61810823500FA85AD_comment":"icon-50.png","7E7966D71810823500FA85AD":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"icon-50@2x.png\"","sourceTree":"\"\""},"7E7966D71810823500FA85AD_comment":"icon-50@2x.png","7E7966D81810823500FA85AD":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"icon-60.png\"","sourceTree":"\"\""},"7E7966D81810823500FA85AD_comment":"icon-60.png","7E7966D91810823500FA85AD":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"icon-60@2x.png\"","sourceTree":"\"\""},"7E7966D91810823500FA85AD_comment":"icon-60@2x.png","7E7966DA1810823500FA85AD":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"icon-76.png\"","sourceTree":"\"\""},"7E7966DA1810823500FA85AD_comment":"icon-76.png","7E7966DB1810823500FA85AD":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"icon-76@2x.png\"","sourceTree":"\"\""},"7E7966DB1810823500FA85AD_comment":"icon-76@2x.png","7E7966DC1810823500FA85AD":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"icon-small.png\"","sourceTree":"\"\""},"7E7966DC1810823500FA85AD_comment":"icon-small.png","7E7966DD1810823500FA85AD":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"icon-small@2x.png\"","sourceTree":"\"\""},"7E7966DD1810823500FA85AD_comment":"icon-small@2x.png","8D1107310486CEB800E47090":{"isa":"PBXFileReference","fileEncoding":4,"lastKnownFileType":"text.plist.xml","name":"\"HelloCordova-Info.plist\"","path":"\"../HelloCordova-Info.plist\"","plistStructureDefinitionIdentifier":"\"com.apple.xcode.plist.structure-definition.iphone.info-plist\"","sourceTree":"\"\""},"8D1107310486CEB800E47090_comment":"HelloCordova-Info.plist","D4A0D8751607E02300AEF8BB":{"isa":"PBXFileReference","lastKnownFileType":"image.png","path":"\"Default-568h@2x~iphone.png\"","sourceTree":"\"\""},"D4A0D8751607E02300AEF8BB_comment":"Default-568h@2x~iphone.png","EB87FDF21871DA7A0020F90C":{"isa":"PBXFileReference","lastKnownFileType":"folder","name":"merges","path":"../../merges","sourceTree":"\"\""},"EB87FDF21871DA7A0020F90C_comment":"merges","EB87FDF31871DA8E0020F90C":{"isa":"PBXFileReference","lastKnownFileType":"folder","name":"www","path":"../../www","sourceTree":"\"\""},"EB87FDF31871DA8E0020F90C_comment":"www","EB87FDF41871DAF40020F90C":{"isa":"PBXFileReference","lastKnownFileType":"text.xml","name":"config.xml","path":"../../config.xml","sourceTree":"\"\""},"EB87FDF41871DAF40020F90C_comment":"config.xml","F840E1F0165FE0F500CFE078":{"isa":"PBXFileReference","lastKnownFileType":"text.xml","name":"config.xml","path":"HelloCordova/config.xml","sourceTree":"\"\""},"F840E1F0165FE0F500CFE078_comment":"config.xml","BF861BABA0714F35A28C9CE1":{"isa":"PBXFileReference","lastKnownFileType":"sourcecode.c.objc","name":"\"CDVLogger.m\"","path":"\"cordova-plugin-console/CDVLogger.m\"","sourceTree":"\"\"","fileEncoding":4},"BF861BABA0714F35A28C9CE1_comment":"CDVLogger.m","E9EE9AB5900F4BDAA302BBF4":{"isa":"PBXFileReference","lastKnownFileType":"sourcecode.c.h","name":"\"CDVLogger.h\"","path":"\"cordova-plugin-console/CDVLogger.h\"","sourceTree":"\"\"","fileEncoding":4},"E9EE9AB5900F4BDAA302BBF4_comment":"CDVLogger.h"},"PBXFrameworksBuildPhase":{"09536AA41B0D118800A1D6F8":{"isa":"PBXFrameworksBuildPhase","buildActionMask":2147483647,"files":[],"runOnlyForDeploymentPostprocessing":0},"09536AA41B0D118800A1D6F8_comment":"Frameworks","1D60588F0D05DD3D006BFB54":{"isa":"PBXFrameworksBuildPhase","buildActionMask":2147483647,"files":[{"value":"5B1594DD16A7569C00FEF299","comment":"AssetsLibrary.framework in Frameworks"},{"value":"301BF552109A68D80062928A","comment":"libCordova.a in Frameworks"},{"value":"288765FD0DF74451002DB57D","comment":"CoreGraphics.framework in Frameworks"},{"value":"305D5FD1115AB8F900A74A75","comment":"MobileCoreServices.framework in Frameworks"}],"runOnlyForDeploymentPostprocessing":0},"1D60588F0D05DD3D006BFB54_comment":"Frameworks"},"PBXGroup":{"080E96DDFE201D6D7F000001":{"isa":"PBXGroup","children":[{"value":"302D95EE14D2391D003F00A1","comment":"MainViewController.h"},{"value":"302D95EF14D2391D003F00A1","comment":"MainViewController.m"},{"value":"302D95F014D2391D003F00A1","comment":"MainViewController.xib"},{"value":"1D3623240D0F684500981E51","comment":"AppDelegate.h"},{"value":"1D3623250D0F684500981E51","comment":"AppDelegate.m"}],"name":"Classes","path":"HelloCordova/Classes","sourceTree":"SOURCE_ROOT"},"080E96DDFE201D6D7F000001_comment":"Classes","09536AA81B0D118800A1D6F8":{"isa":"PBXGroup","children":[{"value":"09536AAC1B0D118800A1D6F8","comment":"InterfaceController.h"},{"value":"09536AAD1B0D118800A1D6F8","comment":"InterfaceController.m"},{"value":"09536AAF1B0D118800A1D6F8","comment":"NotificationController.h"},{"value":"09536AB01B0D118800A1D6F8","comment":"NotificationController.m"},{"value":"09536AB21B0D118800A1D6F8","comment":"Images.xcassets"},{"value":"09536AA91B0D118800A1D6F8","comment":"Supporting Files"}],"path":"\"HelloCordova WatchKit Extension\"","sourceTree":"\"\""},"09536AA81B0D118800A1D6F8_comment":"HelloCordova WatchKit Extension","09536AA91B0D118800A1D6F8":{"isa":"PBXGroup","children":[{"value":"09536AAA1B0D118800A1D6F8","comment":"Info.plist"},{"value":"09536AAB1B0D118800A1D6F8","comment":"PushNotificationPayload.apns"}],"name":"\"Supporting Files\"","sourceTree":"\"\""},"09536AA91B0D118800A1D6F8_comment":"Supporting Files","09536ABA1B0D118900A1D6F8":{"isa":"PBXGroup","children":[{"value":"09536ABD1B0D118900A1D6F8","comment":"Interface.storyboard"},{"value":"09536AC01B0D118900A1D6F8","comment":"Images.xcassets"},{"value":"09536ABB1B0D118900A1D6F8","comment":"Supporting Files"}],"path":"\"HelloCordova WatchKit App\"","sourceTree":"\"\""},"09536ABA1B0D118900A1D6F8_comment":"HelloCordova WatchKit App","09536ABB1B0D118900A1D6F8":{"isa":"PBXGroup","children":[{"value":"09536ABC1B0D118900A1D6F8","comment":"Info.plist"}],"name":"\"Supporting Files\"","sourceTree":"\"\""},"09536ABB1B0D118900A1D6F8_comment":"Supporting Files","19C28FACFE9D520D11CA2CBB":{"isa":"PBXGroup","children":[{"value":"1D6058910D05DD3D006BFB54","comment":"HelloCordova.app"},{"value":"09536AA71B0D118800A1D6F8","comment":"HelloCordova WatchKit Extension.appex"},{"value":"09536AB61B0D118900A1D6F8","comment":"HelloCordova WatchKit App.app"}],"name":"Products","sourceTree":"\"\""},"19C28FACFE9D520D11CA2CBB_comment":"Products","29B97314FDCFA39411CA2CEA":{"isa":"PBXGroup","children":[{"value":"EB87FDF41871DAF40020F90C","comment":"config.xml"},{"value":"EB87FDF31871DA8E0020F90C","comment":"www"},{"value":"EB87FDF21871DA7A0020F90C","comment":"merges"},{"value":"EB87FDF11871DA420020F90C","comment":"Staging"},{"value":"301BF52D109A57CC0062928A","comment":"CordovaLib.xcodeproj"},{"value":"080E96DDFE201D6D7F000001","comment":"Classes"},{"value":"307C750510C5A3420062BCA9","comment":"Plugins"},{"value":"29B97315FDCFA39411CA2CEA","comment":"Other Sources"},{"value":"29B97317FDCFA39411CA2CEA","comment":"Resources"},{"value":"09536AA81B0D118800A1D6F8","comment":"HelloCordova WatchKit Extension"},{"value":"09536ABA1B0D118900A1D6F8","comment":"HelloCordova WatchKit App"},{"value":"29B97323FDCFA39411CA2CEA","comment":"Frameworks"},{"value":"19C28FACFE9D520D11CA2CBB","comment":"Products"}],"name":"CustomTemplate","sourceTree":"\"\""},"29B97314FDCFA39411CA2CEA_comment":"CustomTemplate","29B97315FDCFA39411CA2CEA":{"isa":"PBXGroup","children":[{"value":"32CA4F630368D1EE00C91783","comment":"HelloCordova-Prefix.pch"},{"value":"29B97316FDCFA39411CA2CEA","comment":"main.m"}],"name":"\"Other Sources\"","path":"HelloCordova","sourceTree":"\"\""},"29B97315FDCFA39411CA2CEA_comment":"Other Sources","29B97317FDCFA39411CA2CEA":{"isa":"PBXGroup","children":[{"value":"308D052D1370CCF300D202BF","comment":"icons"},{"value":"308D05311370CCF300D202BF","comment":"splash"},{"value":"8D1107310486CEB800E47090","comment":"HelloCordova-Info.plist"}],"name":"Resources","path":"HelloCordova/Resources","sourceTree":"\"\""},"29B97317FDCFA39411CA2CEA_comment":"Resources","29B97323FDCFA39411CA2CEA":{"isa":"PBXGroup","children":[{"value":"5B1594DC16A7569C00FEF299","comment":"AssetsLibrary.framework"},{"value":"288765FC0DF74451002DB57D","comment":"CoreGraphics.framework"},{"value":"305D5FD0115AB8F900A74A75","comment":"MobileCoreServices.framework"}],"name":"Frameworks","sourceTree":"\"\""},"29B97323FDCFA39411CA2CEA_comment":"Frameworks","301BF52E109A57CC0062928A":{"isa":"PBXGroup","children":[{"value":"301BF535109A57CC0062928A","comment":"libCordova.a"}],"name":"Products","sourceTree":"\"\""},"301BF52E109A57CC0062928A_comment":"Products","307C750510C5A3420062BCA9":{"isa":"PBXGroup","children":[{"value":"BF861BABA0714F35A28C9CE1","comment":"CDVLogger.m"},{"value":"E9EE9AB5900F4BDAA302BBF4","comment":"CDVLogger.h"}],"name":"Plugins","path":"HelloCordova/Plugins","sourceTree":"SOURCE_ROOT"},"307C750510C5A3420062BCA9_comment":"Plugins","308D052D1370CCF300D202BF":{"isa":"PBXGroup","children":[{"value":"30C1856519D5FC0A00212699","comment":"icon-60@3x.png"},{"value":"7E7966D41810823500FA85AD","comment":"icon-40.png"},{"value":"7E7966D51810823500FA85AD","comment":"icon-40@2x.png"},{"value":"7E7966D61810823500FA85AD","comment":"icon-50.png"},{"value":"7E7966D71810823500FA85AD","comment":"icon-50@2x.png"},{"value":"7E7966D81810823500FA85AD","comment":"icon-60.png"},{"value":"7E7966D91810823500FA85AD","comment":"icon-60@2x.png"},{"value":"7E7966DA1810823500FA85AD","comment":"icon-76.png"},{"value":"7E7966DB1810823500FA85AD","comment":"icon-76@2x.png"},{"value":"7E7966DC1810823500FA85AD","comment":"icon-small.png"},{"value":"7E7966DD1810823500FA85AD","comment":"icon-small@2x.png"},{"value":"30FC414816E50CA1004E6F35","comment":"icon-72@2x.png"},{"value":"308D052E1370CCF300D202BF","comment":"icon-72.png"},{"value":"308D052F1370CCF300D202BF","comment":"icon.png"},{"value":"308D05301370CCF300D202BF","comment":"icon@2x.png"}],"path":"icons","sourceTree":"\"\""},"308D052D1370CCF300D202BF_comment":"icons","308D05311370CCF300D202BF":{"isa":"PBXGroup","children":[{"value":"30B4F2FD19D5E07200D9F7D8","comment":"Default-667h.png"},{"value":"30B4F2FE19D5E07200D9F7D8","comment":"Default-736h.png"},{"value":"30B4F2FF19D5E07200D9F7D8","comment":"Default-Landscape-736h.png"},{"value":"D4A0D8751607E02300AEF8BB","comment":"Default-568h@2x~iphone.png"},{"value":"3088BBB7154F3926009F9C59","comment":"Default-Landscape@2x~ipad.png"},{"value":"3088BBB8154F3926009F9C59","comment":"Default-Landscape~ipad.png"},{"value":"3088BBB9154F3926009F9C59","comment":"Default-Portrait@2x~ipad.png"},{"value":"3088BBBA154F3926009F9C59","comment":"Default-Portrait~ipad.png"},{"value":"3088BBBB154F3926009F9C59","comment":"Default@2x~iphone.png"},{"value":"3088BBBC154F3926009F9C59","comment":"Default~iphone.png"}],"path":"splash","sourceTree":"\"\""},"308D05311370CCF300D202BF_comment":"splash","EB87FDF11871DA420020F90C":{"isa":"PBXGroup","children":[{"value":"F840E1F0165FE0F500CFE078","comment":"config.xml"},{"value":"301BF56E109A69640062928A","comment":"www"}],"name":"Staging","sourceTree":"\"\""},"EB87FDF11871DA420020F90C_comment":"Staging"},"PBXNativeTarget":{"09536AA61B0D118800A1D6F8":{"isa":"PBXNativeTarget","buildConfigurationList":"09536ACA1B0D118900A1D6F8","buildConfigurationList_comment":"Build configuration list for PBXNativeTarget \"HelloCordova WatchKit Extension\"","buildPhases":[{"value":"09536AA31B0D118800A1D6F8","comment":"Sources"},{"value":"09536AA41B0D118800A1D6F8","comment":"Frameworks"},{"value":"09536AA51B0D118800A1D6F8","comment":"Resources"}],"buildRules":[],"dependencies":[{"value":"09536AB91B0D118900A1D6F8","comment":"PBXTargetDependency"}],"name":"\"HelloCordova WatchKit Extension\"","productName":"\"HelloCordova WatchKit Extension\"","productReference":"09536AA71B0D118800A1D6F8","productReference_comment":"HelloCordova WatchKit Extension.appex","productType":"\"com.apple.product-type.watchkit-extension\""},"09536AA61B0D118800A1D6F8_comment":"HelloCordova WatchKit Extension","09536AB51B0D118900A1D6F8":{"isa":"PBXNativeTarget","buildConfigurationList":"09536AC91B0D118900A1D6F8","buildConfigurationList_comment":"Build configuration list for PBXNativeTarget \"HelloCordova WatchKit App\"","buildPhases":[{"value":"09536AB41B0D118900A1D6F8","comment":"Resources"}],"buildRules":[],"dependencies":[],"name":"\"HelloCordova WatchKit App\"","productName":"\"HelloCordova WatchKit App\"","productReference":"09536AB61B0D118900A1D6F8","productReference_comment":"HelloCordova WatchKit App.app","productType":"\"com.apple.product-type.application.watchapp\""},"09536AB51B0D118900A1D6F8_comment":"HelloCordova WatchKit App","1D6058900D05DD3D006BFB54":{"isa":"PBXNativeTarget","buildConfigurationList":"1D6058960D05DD3E006BFB54","buildConfigurationList_comment":"Build configuration list for PBXNativeTarget \"HelloCordova\"","buildPhases":[{"value":"304B58A110DAC018002A0835","comment":"Copy www directory"},{"value":"1D60588D0D05DD3D006BFB54","comment":"Resources"},{"value":"1D60588E0D05DD3D006BFB54","comment":"Sources"},{"value":"1D60588F0D05DD3D006BFB54","comment":"Frameworks"},{"value":"09536ACB1B0D118900A1D6F8","comment":"Embed App Extensions"}],"buildRules":[],"dependencies":[{"value":"301BF551109A68C00062928A","comment":"PBXTargetDependency"},{"value":"09536AC31B0D118900A1D6F8","comment":"PBXTargetDependency"}],"name":"HelloCordova","productName":"HelloCordova","productReference":"1D6058910D05DD3D006BFB54","productReference_comment":"HelloCordova.app","productType":"\"com.apple.product-type.application\""},"1D6058900D05DD3D006BFB54_comment":"HelloCordova"},"PBXProject":{"29B97313FDCFA39411CA2CEA":{"isa":"PBXProject","attributes":{"LastUpgradeCheck":510,"TargetAttributes":{"09536AA61B0D118800A1D6F8":{"CreatedOnToolsVersion":"6.3.1"},"09536AB51B0D118900A1D6F8":{"CreatedOnToolsVersion":"6.3.1"}}},"buildConfigurationList":"C01FCF4E08A954540054247B","buildConfigurationList_comment":"Build configuration list for PBXProject \"HelloCordova\"","compatibilityVersion":"\"Xcode 3.2\"","developmentRegion":"English","hasScannedForEncodings":1,"knownRegions":["English","Japanese","French","German","en","es","de","se","Base"],"mainGroup":"29B97314FDCFA39411CA2CEA","mainGroup_comment":"CustomTemplate","projectDirPath":"\"\"","projectReferences":[{"ProductGroup":"301BF52E109A57CC0062928A","ProductGroup_comment":"Products","ProjectRef":"301BF52D109A57CC0062928A","ProjectRef_comment":"CordovaLib.xcodeproj"}],"projectRoot":"\"\"","targets":[{"value":"1D6058900D05DD3D006BFB54","comment":"HelloCordova"},{"value":"09536AA61B0D118800A1D6F8","comment":"HelloCordova WatchKit Extension"},{"value":"09536AB51B0D118900A1D6F8","comment":"HelloCordova WatchKit App"}]},"29B97313FDCFA39411CA2CEA_comment":"Project object"},"PBXReferenceProxy":{"301BF535109A57CC0062928A":{"isa":"PBXReferenceProxy","fileType":"archive.ar","path":"libCordova.a","remoteRef":"301BF534109A57CC0062928A","remoteRef_comment":"PBXContainerItemProxy","sourceTree":"BUILT_PRODUCTS_DIR"},"301BF535109A57CC0062928A_comment":"libCordova.a"},"PBXResourcesBuildPhase":{"09536AA51B0D118800A1D6F8":{"isa":"PBXResourcesBuildPhase","buildActionMask":2147483647,"files":[{"value":"09536AB71B0D118900A1D6F8","comment":"HelloCordova WatchKit App.app in Resources"},{"value":"09536AB31B0D118800A1D6F8","comment":"Images.xcassets in Resources"}],"runOnlyForDeploymentPostprocessing":0},"09536AA51B0D118800A1D6F8_comment":"Resources","09536AB41B0D118900A1D6F8":{"isa":"PBXResourcesBuildPhase","buildActionMask":2147483647,"files":[{"value":"09536ABF1B0D118900A1D6F8","comment":"Interface.storyboard in Resources"},{"value":"09536AC11B0D118900A1D6F8","comment":"Images.xcassets in Resources"}],"runOnlyForDeploymentPostprocessing":0},"09536AB41B0D118900A1D6F8_comment":"Resources","1D60588D0D05DD3D006BFB54":{"isa":"PBXResourcesBuildPhase","buildActionMask":2147483647,"files":[{"value":"7E7966E41810823500FA85AD","comment":"icon-76.png in Resources"},{"value":"7E7966DF1810823500FA85AD","comment":"icon-40@2x.png in Resources"},{"value":"308D05371370CCF300D202BF","comment":"icon-72.png in Resources"},{"value":"30B4F30119D5E07200D9F7D8","comment":"Default-736h.png in Resources"},{"value":"308D05381370CCF300D202BF","comment":"icon.png in Resources"},{"value":"308D05391370CCF300D202BF","comment":"icon@2x.png in Resources"},{"value":"302D95F214D2391D003F00A1","comment":"MainViewController.xib in Resources"},{"value":"7E7966E01810823500FA85AD","comment":"icon-50.png in Resources"},{"value":"7E7966E31810823500FA85AD","comment":"icon-60@2x.png in Resources"},{"value":"7E7966E61810823500FA85AD","comment":"icon-small.png in Resources"},{"value":"3088BBBD154F3926009F9C59","comment":"Default-Landscape@2x~ipad.png in Resources"},{"value":"3088BBBE154F3926009F9C59","comment":"Default-Landscape~ipad.png in Resources"},{"value":"3088BBBF154F3926009F9C59","comment":"Default-Portrait@2x~ipad.png in Resources"},{"value":"7E7966E71810823500FA85AD","comment":"icon-small@2x.png in Resources"},{"value":"3088BBC0154F3926009F9C59","comment":"Default-Portrait~ipad.png in Resources"},{"value":"30B4F30019D5E07200D9F7D8","comment":"Default-667h.png in Resources"},{"value":"7E7966DE1810823500FA85AD","comment":"icon-40.png in Resources"},{"value":"3088BBC1154F3926009F9C59","comment":"Default@2x~iphone.png in Resources"},{"value":"7E7966E21810823500FA85AD","comment":"icon-60.png in Resources"},{"value":"3088BBC2154F3926009F9C59","comment":"Default~iphone.png in Resources"},{"value":"D4A0D8761607E02300AEF8BB","comment":"Default-568h@2x~iphone.png in Resources"},{"value":"30B4F30219D5E07200D9F7D8","comment":"Default-Landscape-736h.png in Resources"},{"value":"30C1856619D5FC0A00212699","comment":"icon-60@3x.png in Resources"},{"value":"7E7966E11810823500FA85AD","comment":"icon-50@2x.png in Resources"},{"value":"7E7966E51810823500FA85AD","comment":"icon-76@2x.png in Resources"},{"value":"30FC414916E50CA1004E6F35","comment":"icon-72@2x.png in Resources"}],"runOnlyForDeploymentPostprocessing":0},"1D60588D0D05DD3D006BFB54_comment":"Resources"},"PBXShellScriptBuildPhase":{"304B58A110DAC018002A0835":{"isa":"PBXShellScriptBuildPhase","buildActionMask":2147483647,"files":[],"inputPaths":[],"name":"\"Copy www directory\"","outputPaths":[],"runOnlyForDeploymentPostprocessing":0,"shellPath":"/bin/sh","shellScript":"\"cordova/lib/copy-www-build-step.sh\"","showEnvVarsInLog":0},"304B58A110DAC018002A0835_comment":"Copy www directory"},"PBXSourcesBuildPhase":{"09536AA31B0D118800A1D6F8":{"isa":"PBXSourcesBuildPhase","buildActionMask":2147483647,"files":[{"value":"09536AB11B0D118800A1D6F8","comment":"NotificationController.m in Sources"},{"value":"09536AAE1B0D118800A1D6F8","comment":"InterfaceController.m in Sources"}],"runOnlyForDeploymentPostprocessing":0},"09536AA31B0D118800A1D6F8_comment":"Sources","1D60588E0D05DD3D006BFB54":{"isa":"PBXSourcesBuildPhase","buildActionMask":2147483647,"files":[{"value":"1D60589B0D05DD56006BFB54","comment":"main.m in Sources"},{"value":"1D3623260D0F684500981E51","comment":"AppDelegate.m in Sources"},{"value":"302D95F114D2391D003F00A1","comment":"MainViewController.m in Sources"},{"value":"88C7083B33E54340BFE0484F","comment":"CDVLogger.m in Sources"},{"value":"BA0D8677B2654B4BB7146A16","comment":"CDVLogger.m in Sources"}],"runOnlyForDeploymentPostprocessing":0},"1D60588E0D05DD3D006BFB54_comment":"Sources"},"PBXTargetDependency":{"09536AB91B0D118900A1D6F8":{"isa":"PBXTargetDependency","target":"09536AB51B0D118900A1D6F8","target_comment":"HelloCordova WatchKit App","targetProxy":"09536AB81B0D118900A1D6F8","targetProxy_comment":"PBXContainerItemProxy"},"09536AB91B0D118900A1D6F8_comment":"PBXTargetDependency","09536AC31B0D118900A1D6F8":{"isa":"PBXTargetDependency","target":"09536AA61B0D118800A1D6F8","target_comment":"HelloCordova WatchKit Extension","targetProxy":"09536AC21B0D118900A1D6F8","targetProxy_comment":"PBXContainerItemProxy"},"09536AC31B0D118900A1D6F8_comment":"PBXTargetDependency","301BF551109A68C00062928A":{"isa":"PBXTargetDependency","name":"CordovaLib","targetProxy":"301BF550109A68C00062928A","targetProxy_comment":"PBXContainerItemProxy"},"301BF551109A68C00062928A_comment":"PBXTargetDependency"},"PBXVariantGroup":{"09536ABD1B0D118900A1D6F8":{"isa":"PBXVariantGroup","children":[{"value":"09536ABE1B0D118900A1D6F8","comment":"Base"}],"name":"Interface.storyboard","sourceTree":"\"\""},"09536ABD1B0D118900A1D6F8_comment":"Interface.storyboard"},"XCBuildConfiguration":{"09536AC51B0D118900A1D6F8":{"isa":"XCBuildConfiguration","buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","CLANG_CXX_LANGUAGE_STANDARD":"\"gnu++0x\"","CLANG_CXX_LIBRARY":"\"libc++\"","CLANG_ENABLE_MODULES":"YES","CLANG_WARN_DIRECT_OBJC_ISA_USAGE":"YES_ERROR","CLANG_WARN_OBJC_ROOT_CLASS":"YES_ERROR","CLANG_WARN_UNREACHABLE_CODE":"YES","COPY_PHASE_STRIP":"NO","DEBUG_INFORMATION_FORMAT":"\"dwarf-with-dsym\"","ENABLE_STRICT_OBJC_MSGSEND":"YES","GCC_C_LANGUAGE_STANDARD":"gnu99","GCC_DYNAMIC_NO_PIC":"NO","GCC_NO_COMMON_BLOCKS":"YES","GCC_OPTIMIZATION_LEVEL":0,"GCC_PREPROCESSOR_DEFINITIONS":["\"DEBUG=1\"","\"$(inherited)\""],"GCC_SYMBOLS_PRIVATE_EXTERN":"NO","GCC_WARN_64_TO_32_BIT_CONVERSION":"YES","GCC_WARN_ABOUT_RETURN_TYPE":"YES_ERROR","GCC_WARN_UNINITIALIZED_AUTOS":"YES_AGGRESSIVE","INFOPLIST_FILE":"\"HelloCordova WatchKit Extension/Info.plist\"","IPHONEOS_DEPLOYMENT_TARGET":"8.3","LD_RUNPATH_SEARCH_PATHS":"\"$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks\"","MTL_ENABLE_DEBUG_INFO":"YES","PRODUCT_NAME":"\"${TARGET_NAME}\"","SKIP_INSTALL":"YES"},"name":"Debug"},"09536AC51B0D118900A1D6F8_comment":"Debug","09536AC61B0D118900A1D6F8":{"isa":"XCBuildConfiguration","buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","CLANG_CXX_LANGUAGE_STANDARD":"\"gnu++0x\"","CLANG_CXX_LIBRARY":"\"libc++\"","CLANG_ENABLE_MODULES":"YES","CLANG_WARN_DIRECT_OBJC_ISA_USAGE":"YES_ERROR","CLANG_WARN_OBJC_ROOT_CLASS":"YES_ERROR","CLANG_WARN_UNREACHABLE_CODE":"YES","COPY_PHASE_STRIP":"NO","DEBUG_INFORMATION_FORMAT":"\"dwarf-with-dsym\"","ENABLE_NS_ASSERTIONS":"NO","ENABLE_STRICT_OBJC_MSGSEND":"YES","GCC_C_LANGUAGE_STANDARD":"gnu99","GCC_NO_COMMON_BLOCKS":"YES","GCC_WARN_64_TO_32_BIT_CONVERSION":"YES","GCC_WARN_ABOUT_RETURN_TYPE":"YES_ERROR","GCC_WARN_UNINITIALIZED_AUTOS":"YES_AGGRESSIVE","INFOPLIST_FILE":"\"HelloCordova WatchKit Extension/Info.plist\"","IPHONEOS_DEPLOYMENT_TARGET":"8.3","LD_RUNPATH_SEARCH_PATHS":"\"$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks\"","MTL_ENABLE_DEBUG_INFO":"NO","PRODUCT_NAME":"\"${TARGET_NAME}\"","SKIP_INSTALL":"YES","VALIDATE_PRODUCT":"YES"},"name":"Release"},"09536AC61B0D118900A1D6F8_comment":"Release","09536AC71B0D118900A1D6F8":{"isa":"XCBuildConfiguration","buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","ASSETCATALOG_COMPILER_APPICON_NAME":"AppIcon","CLANG_CXX_LANGUAGE_STANDARD":"\"gnu++0x\"","CLANG_CXX_LIBRARY":"\"libc++\"","CLANG_ENABLE_MODULES":"YES","CLANG_WARN_DIRECT_OBJC_ISA_USAGE":"YES_ERROR","CLANG_WARN_OBJC_ROOT_CLASS":"YES_ERROR","CLANG_WARN_UNREACHABLE_CODE":"YES","COPY_PHASE_STRIP":"NO","DEBUG_INFORMATION_FORMAT":"\"dwarf-with-dsym\"","ENABLE_STRICT_OBJC_MSGSEND":"YES","GCC_C_LANGUAGE_STANDARD":"gnu99","GCC_DYNAMIC_NO_PIC":"NO","GCC_NO_COMMON_BLOCKS":"YES","GCC_OPTIMIZATION_LEVEL":0,"GCC_PREPROCESSOR_DEFINITIONS":["\"DEBUG=1\"","\"$(inherited)\""],"GCC_SYMBOLS_PRIVATE_EXTERN":"NO","GCC_WARN_64_TO_32_BIT_CONVERSION":"YES","GCC_WARN_ABOUT_RETURN_TYPE":"YES_ERROR","GCC_WARN_UNINITIALIZED_AUTOS":"YES_AGGRESSIVE","IBSC_MODULE":"HelloCordova_WatchKit_Extension","INFOPLIST_FILE":"\"HelloCordova WatchKit App/Info.plist\"","IPHONEOS_DEPLOYMENT_TARGET":"8.3","MTL_ENABLE_DEBUG_INFO":"YES","PRODUCT_NAME":"\"$(TARGET_NAME)\"","SKIP_INSTALL":"YES","TARGETED_DEVICE_FAMILY":4,"\"TARGETED_DEVICE_FAMILY[sdk=iphonesimulator*]\"":"\"1,4\""},"name":"Debug"},"09536AC71B0D118900A1D6F8_comment":"Debug","09536AC81B0D118900A1D6F8":{"isa":"XCBuildConfiguration","buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","ASSETCATALOG_COMPILER_APPICON_NAME":"AppIcon","CLANG_CXX_LANGUAGE_STANDARD":"\"gnu++0x\"","CLANG_CXX_LIBRARY":"\"libc++\"","CLANG_ENABLE_MODULES":"YES","CLANG_WARN_DIRECT_OBJC_ISA_USAGE":"YES_ERROR","CLANG_WARN_OBJC_ROOT_CLASS":"YES_ERROR","CLANG_WARN_UNREACHABLE_CODE":"YES","COPY_PHASE_STRIP":"NO","DEBUG_INFORMATION_FORMAT":"\"dwarf-with-dsym\"","ENABLE_NS_ASSERTIONS":"NO","ENABLE_STRICT_OBJC_MSGSEND":"YES","GCC_C_LANGUAGE_STANDARD":"gnu99","GCC_NO_COMMON_BLOCKS":"YES","GCC_WARN_64_TO_32_BIT_CONVERSION":"YES","GCC_WARN_ABOUT_RETURN_TYPE":"YES_ERROR","GCC_WARN_UNINITIALIZED_AUTOS":"YES_AGGRESSIVE","IBSC_MODULE":"HelloCordova_WatchKit_Extension","INFOPLIST_FILE":"\"HelloCordova WatchKit App/Info.plist\"","IPHONEOS_DEPLOYMENT_TARGET":"8.3","MTL_ENABLE_DEBUG_INFO":"NO","PRODUCT_NAME":"\"$(TARGET_NAME)\"","SKIP_INSTALL":"YES","TARGETED_DEVICE_FAMILY":4,"\"TARGETED_DEVICE_FAMILY[sdk=iphonesimulator*]\"":"\"1,4\"","VALIDATE_PRODUCT":"YES"},"name":"Release"},"09536AC81B0D118900A1D6F8_comment":"Release","1D6058940D05DD3E006BFB54":{"isa":"XCBuildConfiguration","buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","CLANG_ENABLE_OBJC_ARC":"YES","COPY_PHASE_STRIP":"NO","GCC_DYNAMIC_NO_PIC":"NO","GCC_OPTIMIZATION_LEVEL":0,"GCC_PRECOMPILE_PREFIX_HEADER":"YES","GCC_PREFIX_HEADER":"\"HelloCordova/HelloCordova-Prefix.pch\"","GCC_THUMB_SUPPORT":"NO","GCC_VERSION":"\"\"","INFOPLIST_FILE":"\"HelloCordova/HelloCordova-Info.plist\"","IPHONEOS_DEPLOYMENT_TARGET":"6.0","OTHER_LDFLAGS":["\"-weak_framework\"","CoreFoundation","\"-weak_framework\"","UIKit","\"-weak_framework\"","AVFoundation","\"-weak_framework\"","CoreMedia","\"-weak-lSystem\"","\"-ObjC\""],"PRODUCT_NAME":"HelloCordova","TARGETED_DEVICE_FAMILY":"\"1,2\""},"name":"Debug"},"1D6058940D05DD3E006BFB54_comment":"Debug","1D6058950D05DD3E006BFB54":{"isa":"XCBuildConfiguration","buildSettings":{"ALWAYS_SEARCH_USER_PATHS":"NO","CLANG_ENABLE_OBJC_ARC":"YES","COPY_PHASE_STRIP":"YES","GCC_PRECOMPILE_PREFIX_HEADER":"YES","GCC_PREFIX_HEADER":"\"HelloCordova/HelloCordova-Prefix.pch\"","GCC_THUMB_SUPPORT":"NO","GCC_VERSION":"\"\"","INFOPLIST_FILE":"\"HelloCordova/HelloCordova-Info.plist\"","IPHONEOS_DEPLOYMENT_TARGET":"6.0","OTHER_LDFLAGS":["\"-weak_framework\"","CoreFoundation","\"-weak_framework\"","UIKit","\"-weak_framework\"","AVFoundation","\"-weak_framework\"","CoreMedia","\"-weak-lSystem\"","\"-ObjC\""],"PRODUCT_NAME":"HelloCordova","TARGETED_DEVICE_FAMILY":"\"1,2\""},"name":"Release"},"1D6058950D05DD3E006BFB54_comment":"Release","C01FCF4F08A954540054247B":{"isa":"XCBuildConfiguration","buildSettings":{"CLANG_ENABLE_OBJC_ARC":"YES","CLANG_WARN_BOOL_CONVERSION":"YES","CLANG_WARN_CONSTANT_CONVERSION":"YES","CLANG_WARN_EMPTY_BODY":"YES","CLANG_WARN_ENUM_CONVERSION":"YES","CLANG_WARN_INT_CONVERSION":"YES","CLANG_WARN__DUPLICATE_METHOD_MATCH":"YES","\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\"":"\"iPhone Developer\"","GCC_C_LANGUAGE_STANDARD":"c99","GCC_THUMB_SUPPORT":"NO","GCC_VERSION":"\"\"","GCC_WARN_ABOUT_RETURN_TYPE":"YES","GCC_WARN_UNDECLARED_SELECTOR":"YES","GCC_WARN_UNINITIALIZED_AUTOS":"YES","GCC_WARN_UNUSED_FUNCTION":"YES","GCC_WARN_UNUSED_VARIABLE":"YES","HEADER_SEARCH_PATHS":["\"\\\"$(TARGET_BUILD_DIR)/usr/local/lib/include\\\"\"","\"\\\"$(OBJROOT)/UninstalledProducts/include\\\"\"","\"\\\"$(BUILT_PRODUCTS_DIR)\\\"\""],"IPHONEOS_DEPLOYMENT_TARGET":"6.0","ONLY_ACTIVE_ARCH":"YES","OTHER_LDFLAGS":["\"-weak_framework\"","CoreFoundation","\"-weak_framework\"","UIKit","\"-weak_framework\"","AVFoundation","\"-weak_framework\"","CoreMedia","\"-weak-lSystem\"","\"-ObjC\""],"SDKROOT":"iphoneos","SKIP_INSTALL":"NO","USER_HEADER_SEARCH_PATHS":"\"\""},"name":"Debug"},"C01FCF4F08A954540054247B_comment":"Debug","C01FCF5008A954540054247B":{"isa":"XCBuildConfiguration","buildSettings":{"CLANG_ENABLE_OBJC_ARC":"YES","CLANG_WARN_BOOL_CONVERSION":"YES","CLANG_WARN_CONSTANT_CONVERSION":"YES","CLANG_WARN_EMPTY_BODY":"YES","CLANG_WARN_ENUM_CONVERSION":"YES","CLANG_WARN_INT_CONVERSION":"YES","CLANG_WARN__DUPLICATE_METHOD_MATCH":"YES","\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\"":"\"iPhone Developer\"","GCC_C_LANGUAGE_STANDARD":"c99","GCC_THUMB_SUPPORT":"NO","GCC_VERSION":"\"\"","GCC_WARN_ABOUT_RETURN_TYPE":"YES","GCC_WARN_UNDECLARED_SELECTOR":"YES","GCC_WARN_UNINITIALIZED_AUTOS":"YES","GCC_WARN_UNUSED_FUNCTION":"YES","GCC_WARN_UNUSED_VARIABLE":"YES","HEADER_SEARCH_PATHS":["\"\\\"$(TARGET_BUILD_DIR)/usr/local/lib/include\\\"\"","\"\\\"$(OBJROOT)/UninstalledProducts/include\\\"\"","\"\\\"$(BUILT_PRODUCTS_DIR)\\\"\""],"IPHONEOS_DEPLOYMENT_TARGET":"6.0","OTHER_LDFLAGS":["\"-weak_framework\"","CoreFoundation","\"-weak_framework\"","UIKit","\"-weak_framework\"","AVFoundation","\"-weak_framework\"","CoreMedia","\"-weak-lSystem\"","\"-ObjC\""],"SDKROOT":"iphoneos","SKIP_INSTALL":"NO","USER_HEADER_SEARCH_PATHS":"\"\""},"name":"Release"},"C01FCF5008A954540054247B_comment":"Release"},"XCConfigurationList":{"09536AC91B0D118900A1D6F8":{"isa":"XCConfigurationList","buildConfigurations":[{"value":"09536AC71B0D118900A1D6F8","comment":"Debug"},{"value":"09536AC81B0D118900A1D6F8","comment":"Release"}],"defaultConfigurationIsVisible":0,"defaultConfigurationName":"Release"},"09536AC91B0D118900A1D6F8_comment":"Build configuration list for PBXNativeTarget \"HelloCordova WatchKit App\"","09536ACA1B0D118900A1D6F8":{"isa":"XCConfigurationList","buildConfigurations":[{"value":"09536AC51B0D118900A1D6F8","comment":"Debug"},{"value":"09536AC61B0D118900A1D6F8","comment":"Release"}],"defaultConfigurationIsVisible":0,"defaultConfigurationName":"Release"},"09536ACA1B0D118900A1D6F8_comment":"Build configuration list for PBXNativeTarget \"HelloCordova WatchKit Extension\"","1D6058960D05DD3E006BFB54":{"isa":"XCConfigurationList","buildConfigurations":[{"value":"1D6058940D05DD3E006BFB54","comment":"Debug"},{"value":"1D6058950D05DD3E006BFB54","comment":"Release"}],"defaultConfigurationIsVisible":0,"defaultConfigurationName":"Release"},"1D6058960D05DD3E006BFB54_comment":"Build configuration list for PBXNativeTarget \"HelloCordova\"","C01FCF4E08A954540054247B":{"isa":"XCConfigurationList","buildConfigurations":[{"value":"C01FCF4F08A954540054247B","comment":"Debug"},{"value":"C01FCF5008A954540054247B","comment":"Release"}],"defaultConfigurationIsVisible":0,"defaultConfigurationName":"Release"},"C01FCF4E08A954540054247B_comment":"Build configuration list for PBXProject \"HelloCordova\""}},"rootObject":"29B97313FDCFA39411CA2CEA","rootObject_comment":"Project object"},"headComment":"!$*UTF8*$!"} diff --git a/test/fixtures/single-data-model.xcdatamodeld/SingleDataModel.xcdatamodel/contents b/test/fixtures/single-data-model.xcdatamodeld/SingleDataModel.xcdatamodel/contents new file mode 100644 index 0000000..6bd3dcd --- /dev/null +++ b/test/fixtures/single-data-model.xcdatamodeld/SingleDataModel.xcdatamodel/contents @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/test/group.js b/test/group.js new file mode 100644 index 0000000..b907c7e --- /dev/null +++ b/test/group.js @@ -0,0 +1,379 @@ +var pbx = require('../lib/pbxProject'), + project, + projectHash; + +var findChildInGroup = function(obj, target) { + var found = false; + + for (var i = 0, j = obj.children.length; i < j; i++) { + if (obj.children[i].value === target) { + found = true; + break; + } + } + + return found; +} + +var findFileByUUID = function(obj, target) { + var found = false; + + for (var k = 0, l = obj.files.length; k < l; k++) { + if (obj.files[k].value === target) { + found = true; + break; + } + } + + return found; +} + +var findByFileRef = function(obj, target) { + var found = false; + + for (var property in obj) { + if (!/comment/.test(property)) { + if (obj[property].fileRef === target) { + found = true; + break; + } + } + } + return found; +} + +var findByName = function(obj, target) { + var found = false; + for (var property in obj) { + if (!/comment/.test(property)) { + var value = obj[property]; + if (value.name === target) { + found = true; + } + } + } + return found; +} + +exports.setUp = function(callback) { + project = new pbx('test/parser/projects/group.pbxproj'); + projectHash = project.parseSync(); + callback(); +} + +exports.getGroupByKey = { + 'should return PBXGroup for Classes': function(test) { + var groupKey = project.findPBXGroupKey({name: 'Classes'}); + var group = project.getPBXGroupByKey(groupKey); + test.ok(group.name === 'Classes'); + test.done(); + }, + 'should return PBXGroup for Plugins': function(test) { + var groupKey = project.findPBXGroupKey({name: 'Plugins'}); + var group = project.getPBXGroupByKey(groupKey); + test.ok(group.name === 'Plugins'); + test.done(); + } +} + +exports.createGroup = { + 'should create a new Test Group': function(test) { + var found = false; + var groups = project.getPBXObject('PBXGroup'); + + var found = findByName(groups, 'Test'); + test.ok(found === false); + + + var group = project.findPBXGroupKey({name:'Test'}); + test.ok(group === undefined); + + project.pbxCreateGroup('Test', 'Test'); + + groups = project.getPBXObject('PBXGroup'); + found = findByName(groups, 'Test'); + test.ok(found === true); + + group = project.findPBXGroupKey({name:'Test'}); + test.ok(typeof group === 'string'); + test.done(); + } +} + +exports.findGroupKey = { + 'should return a valid group key':function(test) { + var keyByName = project.findPBXGroupKey({ name: 'Classes'}); + var keyByPath = project.findPBXGroupKey({ path: 'icons'}); + var keyByPathName = project.findPBXGroupKey({ path: '"HelloCordova/Plugins"', name: 'Plugins'}); + var nonExistingKey = project.findPBXGroupKey({ name: 'Foo'}); + + test.ok(keyByName === '080E96DDFE201D6D7F000001'); + test.ok(keyByPath === '308D052D1370CCF300D202BF'); + test.ok(keyByPathName === '307C750510C5A3420062BCA9'); + test.ok(nonExistingKey === undefined); + + test.done(); + } +} + +exports.addGroupToGroup = { + 'should create a new test group then add group to Classes group': function(test) { + var testKey = project.pbxCreateGroup('Test', 'Test'); + var classesKey = project.findPBXGroupKey({name: 'Classes'}); + project.addToPbxGroup(testKey, classesKey); + + var classesGroup = project.getPBXGroupByKey(classesKey); + var foundTestGroup = false; + for (var i = 0, j = classesGroup.children.length; i < j; i++) { + var child = classesGroup.children[i]; + if (child.value === testKey && child.comment === 'Test') { + foundTestGroup = true; + } + } + + test.ok(foundTestGroup); + + test.done(); + } +} + +exports.addSourceFileToGroup = { + 'should create group + add source file' : function(test) { + var testKey = project.pbxCreateGroup('Test', 'Test'); + var file = project.addSourceFile('Notifications.m', {}, testKey); + + var foundInGroup = findChildInGroup(project.getPBXGroupByKey(testKey),file.fileRef ); + test.ok(foundInGroup); + + var foundInBuildFileSection = findByFileRef(project.pbxBuildFileSection(), file.fileRef); + test.ok(foundInBuildFileSection); + + var foundInBuildPhase = findFileByUUID(project.pbxSourcesBuildPhaseObj(), file.uuid); + test.ok(foundInBuildPhase); + + test.done(); + } +} + +exports.removeSourceFileFromGroup = { + 'should create group + add source file then remove source file' : function(test) { + var testKey = project.pbxCreateGroup('Test', 'Test'); + var file = project.addSourceFile('Notifications.m', {}, testKey); + + var foundInGroup = findChildInGroup(project.getPBXGroupByKey(testKey),file.fileRef ); + test.ok(foundInGroup); + + var foundInBuildFileSection = findByFileRef(project.pbxBuildFileSection(), file.fileRef); + test.ok(foundInBuildFileSection); + + var foundInBuildPhase = findFileByUUID(project.pbxSourcesBuildPhaseObj(), file.uuid); + test.ok(foundInBuildPhase); + + project.removeSourceFile('Notifications.m', {}, testKey); + + var foundInGroup = findChildInGroup(project.getPBXGroupByKey(testKey),file.fileRef ); + test.ok(!foundInGroup); + + var foundInBuildFileSection = findByFileRef(project.pbxBuildFileSection(), file.fileRef); + test.ok(!foundInBuildFileSection); + + var foundInBuildPhase = findFileByUUID(project.pbxSourcesBuildPhaseObj(), file.uuid); + test.ok(!foundInBuildPhase); + + test.done(); + } +} + +exports.addHeaderFileToGroup = { + 'should create group + add header file' : function(test) { + var testKey = project.pbxCreateGroup('Test', 'Test'); + var file = project.addHeaderFile('Notifications.h', {}, testKey); + + var foundInGroup = findChildInGroup(project.getPBXGroupByKey(testKey),file.fileRef ); + test.ok(foundInGroup); + + test.done(); + } +} + +exports.removeHeaderFileFromGroup = { + 'should create group + add source file then remove header file' : function(test) { + var testKey = project.pbxCreateGroup('Test', 'Test'); + var file = project.addHeaderFile('Notifications.h', {}, testKey); + + var foundInGroup = findChildInGroup(project.getPBXGroupByKey(testKey),file.fileRef ); + test.ok(foundInGroup); + + project.removeHeaderFile('Notifications.h', {}, testKey); + + var foundInGroup = findChildInGroup(project.getPBXGroupByKey(testKey),file.fileRef ); + test.ok(!foundInGroup); + + test.done(); + } +} + +exports.addResourceFileToGroup = { + 'should add resource file (PNG) to the splash group' : function(test) { + + var testKey = project.findPBXGroupKey({path:'splash'}); + var file = project.addResourceFile('DefaultTest-667h.png', {}, testKey); + + var foundInGroup = findChildInGroup(project.getPBXGroupByKey(testKey),file.fileRef ); + test.ok(foundInGroup); + + test.done(); + } +} + +exports.removeResourceFileFromGroup = { + 'should add resource file (PNG) then remove resource file from splash group' : function(test) { + var testKey = project.findPBXGroupKey({path:'splash'}); + var file = project.addResourceFile('DefaultTest-667h.png', {}, testKey); + + var foundInGroup = findChildInGroup(project.getPBXGroupByKey(testKey),file.fileRef ); + test.ok(foundInGroup); + + project.removeResourceFile('DefaultTest-667h.png', {}, testKey); + + var foundInGroup = findChildInGroup(project.getPBXGroupByKey(testKey),file.fileRef ); + test.ok(!foundInGroup); + + test.done(); + } +} + +exports.retrieveBuildPropertyForBuild = { + 'should retrieve valid build property ':function(test) { + var releaseTargetedDeviceFamily = project.getBuildProperty('TARGETED_DEVICE_FAMILY', 'Release'); + var debugTargetedDeviceFamily = project.getBuildProperty('TARGETED_DEVICE_FAMILY', 'Debug'); + var nonExistingProperty = project.getBuildProperty('FOO', 'Debug'); + var nonExistingBuild = project.getBuildProperty('TARGETED_DEVICE_FAMILY', 'Foo'); + + test.equal(releaseTargetedDeviceFamily, '"1,2"'); + test.equal(debugTargetedDeviceFamily,'"1"'); + test.equal(nonExistingProperty, undefined); + test.equal(nonExistingBuild, undefined); + + test.done(); + } +} + +exports.retrieveBuildConfigByName = { + 'should retrieve valid build config':function(test) { + var releaseBuildConfig = project.getBuildConfigByName('Release'); + for (var property in releaseBuildConfig) { + var value = releaseBuildConfig[property]; + test.ok(value.name === 'Release'); + } + + var debugBuildConfig = project.getBuildConfigByName('Debug'); + for (var property in debugBuildConfig) { + var value = debugBuildConfig[property]; + test.ok(value.name === 'Debug'); + } + + var nonExistingBuildConfig = project.getBuildConfigByName('Foo'); + test.deepEqual(nonExistingBuildConfig, {}); + + test.done(); + } +} + +/* This proves the issue in 0.6.7 +exports.validatePropReplaceException = { + 'should throw TypeError for updateBuildProperty VALID_ARCHS when none existed' : function(test) { + test.throws( + function() { + project.updateBuildProperty('VALID_ARCHS', '"armv7 armv7s'); + }, + TypeError, + "Object object has no method 'hasOwnProperty'" + ); + test.done(); + } +} +*/ + +exports.validatePropReplaceFix = { + 'should create build configuration for VALID_ARCHS when none existed' : function(test) { + project.updateBuildProperty('VALID_ARCHS', '"armv7 armv7s"', 'Debug'); + test.done(); + } +} + +exports.validateHasFile = { + 'should return true for has file MainViewController.m': function(test) { + var result = project.hasFile('MainViewController.m'); + test.ok(result.path == "MainViewController.m"); + test.done(); + } +} + +exports.testWritingPBXProject = { + 'should successfully write to PBXProject TargetAttributes': function(test) { + var pbxProjectObj = project.getPBXObject('PBXProject'); + var pbxProject; + for (var property in pbxProjectObj) { + if (!/comment/.test(property)) { + pbxProject = pbxProjectObj[property]; + } + } + + var target; + var projectTargets = pbxProject.targets; + for (var i = 0, j = pbxProject.targets.length; i < j; i++ ) { + target = pbxProject.targets[i].value; + } + + pbxProject.attributes.TargetAttributes = {}; + pbxProject.attributes.TargetAttributes[target] = { + DevelopmentTeam: 'N6X4RJZZ5D', + SystemCapabilities: { + "com.apple.BackgroundModes": { + enabled : 0 + }, + "com.apple.DataProtection" : { + enabled : 0 + }, + "com.apple.Keychain" : { + enabled: 1 + } + } + }; + + var output = project.writeSync(); + + test.done(); + }, + 'should add target attribute to PBXProject TargetAttributes': function(test) { + project.addTargetAttribute('ProvisioningStyle', 'Manual'); + var output = project.writeSync(); + test.equal(output.match(/ProvisioningStyle\s*=\s*Manual/g).length, 1); + + test.done(); + }, + 'should change target attribute at PBXProject TargetAttributes': function(test) { + project.addTargetAttribute('ProvisioningStyle', 'Manual'); + var output = project.writeSync(); + test.equal(output.match(/ProvisioningStyle\s*=\s*Manual/g).length, 1); + + project.addTargetAttribute('ProvisioningStyle', 'Automatic'); + output = project.writeSync(); + test.equal(output.match(/ProvisioningStyle\s*=\s*Manual/g), null); + test.equal(output.match(/ProvisioningStyle\s*=\s*Automatic/g).length, 1); + + test.done(); + }, + 'should remove target attribute from PBXProject TargetAttributes': function(test) { + project.addTargetAttribute('ProvisioningStyle', 'Manual'); + var output = project.writeSync(); + test.equal(output.match(/ProvisioningStyle\s*=\s*Manual/g).length, 1); + + project.removeTargetAttribute('ProvisioningStyle'); + output = project.writeSync(); + test.equal(output.match(/ProvisioningStyle\s*=\s*Manual/g), null); + + test.done(); + } +} diff --git a/test/knownRegions.js b/test/knownRegions.js new file mode 100644 index 0000000..8418d58 --- /dev/null +++ b/test/knownRegions.js @@ -0,0 +1,76 @@ +var fullProject = require('./fixtures/full-project') + fullProjectStr = JSON.stringify(fullProject), + pbx = require('../lib/pbxProject'), + project = new pbx('.'); + +function cleanHash() { + return JSON.parse(fullProjectStr); +} + +exports.setUp = function (callback) { + project.hash = cleanHash(); + callback(); +} + +exports.addKnownRegion = { + 'should add new region to existing knownRegions': function (test) { + var knownRegions = project.pbxProjectSection()[project.getFirstProject()['uuid']]['knownRegions']; + test.equal(knownRegions.indexOf('Spanish'), -1); + + project.addKnownRegion('Spanish') + knownRegions = project.pbxProjectSection()[project.getFirstProject()['uuid']]['knownRegions']; + test.notEqual(knownRegions.indexOf('Spanish'), -1); + test.done(); + }, + + 'should not add region if it already exists in knownRegions': function (test) { + var numberOfRegions = project.pbxProjectSection()[project.getFirstProject()['uuid']]['knownRegions'].length; + + project.addKnownRegion('German'); + var newNumberOfRegions = project.pbxProjectSection()[project.getFirstProject()['uuid']]['knownRegions'].length; + test.equal(numberOfRegions, newNumberOfRegions); + test.done(); + }, + + 'should create knownRegions array if it does not exist': function (test) { + delete project.pbxProjectSection()[project.getFirstProject()['uuid']]['knownRegions']; + test.ok(!project.pbxProjectSection()[project.getFirstProject()['uuid']]['knownRegions']); + + project.addKnownRegion('German') + test.ok(project.pbxProjectSection()[project.getFirstProject()['uuid']]['knownRegions']); + test.done(); + }, +} + +exports.removeKnownRegion = { + 'should remove named region from knownRegions': function (test) { + var knownRegions = project.pbxProjectSection()[project.getFirstProject()['uuid']]['knownRegions']; + test.notEqual(knownRegions.indexOf('German'), -1); + + project.removeKnownRegion('German'); + knownRegions = project.pbxProjectSection()[project.getFirstProject()['uuid']]['knownRegions']; + test.equal(knownRegions.indexOf('German'), -1); + test.done(); + }, + + 'should do nothing if named region does not exist in knownRegions': function (test) { + let numberOfRegions = project.pbxProjectSection()[project.getFirstProject()['uuid']]['knownRegions'].length; + + project.removeKnownRegion('Korean'); + let newNumberOfRegions = project.pbxProjectSection()[project.getFirstProject()['uuid']]['knownRegions'].length; + test.equal(numberOfRegions, newNumberOfRegions); + test.done(); + }, +} + +exports.hasKnownRegion = { + 'should return true if named region exists in knownRegions': function (test) { + test.ok(project.hasKnownRegion('German')); + test.done(); + }, + + 'should return false if named region does not exist in knownRegions': function (test) { + test.ok(!project.hasKnownRegion('Ducth')); + test.done(); + }, +} diff --git a/test/multipleTargets.js b/test/multipleTargets.js new file mode 100644 index 0000000..2ef3d4b --- /dev/null +++ b/test/multipleTargets.js @@ -0,0 +1,153 @@ +var fullProject = require('./fixtures/multiple-targets') + fullProjectStr = JSON.stringify(fullProject), + pbx = require('../lib/pbxProject'), + pbxFile = require('../lib/pbxFile'), + proj = new pbx('.'); + +function cleanHash() { + return JSON.parse(fullProjectStr); +} + +exports.setUp = function (callback) { + proj.hash = cleanHash(); + callback(); +} + +exports.addFilesToTarget = { + 'should add the file to a proper target': function (test) { + + var target = "1D6058900D05DD3D006BFB54"; + var filename = "file.m"; + + var opt = { target : target }; + var newFile = proj.addSourceFile(filename,opt); + + test.equal(newFile.constructor, pbxFile); + + var sources = proj.pbxSourcesBuildPhaseObj(target); + test.equal(sources.files[5].comment, filename+" in Sources"); + + test.done(); + }, + 'should remove the file from the proper target': function (test) { + + var target = "1D6058900D05DD3D006BFB54"; + var filename = "file.m"; + + var opt = { target : target }; + var newFile = proj.addSourceFile(filename,opt); + + test.equal(newFile.constructor, pbxFile); + + var sources = proj.pbxSourcesBuildPhaseObj(target); + test.equal(sources.files[5].comment, filename+" in Sources"); + var l = sources.files.length; + + proj.removeSourceFile(filename,opt); + var sources = proj.pbxSourcesBuildPhaseObj(target); + test.equal(sources.files.length,l-1); + + test.done(); + }, + 'should fail when specifying an invalid target': function (test) { + + var target = "XXXXX"; + var filename = "file.m"; + + var opt = { target : target }; + test.throws(function(){ + proj.addSourceFile(filename,opt); + }); + + + test.done(); + }, + 'should add the library to a proper target': function (test) { + + var target = "1D6058900D05DD3D006BFB54"; + var filename = "library.lib"; + + var opt = { target : target }; + var newFile = proj.addStaticLibrary(filename,opt); + + test.equal(newFile.constructor, pbxFile); + + var libraries = proj.pbxFrameworksBuildPhaseObj(target); + test.equal(libraries.files[4].comment, filename+" in Resources"); + + test.done(); + }, + 'should remove the library to a proper target': function (test) { + + var target = "1D6058900D05DD3D006BFB54"; + var filename = "library.lib"; + + var opt = { target : target }; + var newFile = proj.addStaticLibrary(filename,opt); + + test.equal(newFile.constructor, pbxFile); + + var libraries = proj.pbxFrameworksBuildPhaseObj(target); + test.equal(libraries.files[4].comment, filename+" in Resources"); + var l = libraries.files.length; + + proj.removeFramework(filename,opt); + var libraries = proj.pbxFrameworksBuildPhaseObj(target); + test.equal(libraries.files.length,l-1); + + test.done(); + + }, + 'should add the framework to a proper target': function (test) { + + var target = "1D6058900D05DD3D006BFB54"; + var filename = "delta.framework"; + + var opt = { target : target }; + var newFile = proj.addFramework(filename,opt); + + test.equal(newFile.constructor, pbxFile); + + var frameworks = proj.pbxFrameworksBuildPhaseObj(target); + test.equal(frameworks.files[4].comment, filename+" in Frameworks"); + + test.done(); + }, + 'should add a ressource fileto a proper target': function (test) { + + var target = "1D6058900D05DD3D006BFB54"; + var filename = "delta.png"; + + var opt = { target : target }; + var newFile = proj.addResourceFile(filename,opt); + + test.equal(newFile.constructor, pbxFile); + + var resources = proj.pbxResourcesBuildPhaseObj(target); + test.equal(resources.files[26].comment, filename+" in Resources"); + + test.done(); + }, + 'should remove a ressource file from a proper target': function (test) { + + var target = "1D6058900D05DD3D006BFB54"; + var filename = "delta.png"; + + var opt = { target : target }; + var newFile = proj.addResourceFile(filename,opt); + + test.equal(newFile.constructor, pbxFile); + + var resources = proj.pbxResourcesBuildPhaseObj(target); + test.equal(resources.files[26].comment, filename+" in Resources"); + + var l = resources.files.length; + + proj.removeResourceFile(filename,opt); + var resources = proj.pbxResourcesBuildPhaseObj(target); + test.equal(resources.files.length,l-1); + + test.done(); + }, +} + diff --git a/test/parser/build-config.js b/test/parser/build-config.js index 20eb5cf..fa7e52c 100644 --- a/test/parser/build-config.js +++ b/test/parser/build-config.js @@ -2,7 +2,7 @@ var PEG = require('pegjs'), fs = require('fs'), pbx = fs.readFileSync('test/parser/projects/build-config.pbxproj', 'utf-8'), grammar = fs.readFileSync('lib/parser/pbxproj.pegjs', 'utf-8'), - parser = PEG.buildParser(grammar), + parser = PEG.generate(grammar), rawProj = parser.parse(pbx), util = require('util'), project = rawProj.project; diff --git a/test/parser/comments.js b/test/parser/comments.js index c44727c..a97c6c3 100644 --- a/test/parser/comments.js +++ b/test/parser/comments.js @@ -2,7 +2,7 @@ var PEG = require('pegjs'), fs = require('fs'), pbx = fs.readFileSync('test/parser/projects/comments.pbxproj', 'utf-8'), grammar = fs.readFileSync('lib/parser/pbxproj.pegjs', 'utf-8'), - parser = PEG.buildParser(grammar); + parser = PEG.generate(grammar); // Cordova 1.8 has the Apache headers as comments in the pbxproj file // I DON'T KNOW WHY diff --git a/test/parser/dotsInNames.js b/test/parser/dotsInNames.js new file mode 100644 index 0000000..f5c0070 --- /dev/null +++ b/test/parser/dotsInNames.js @@ -0,0 +1,15 @@ +var PEG = require('pegjs'), + fs = require('fs'), + pbx = fs.readFileSync('test/parser/projects/dots-in-names.pbxproj', 'utf-8'), + grammar = fs.readFileSync('lib/parser/pbxproj.pegjs', 'utf-8'), + parser = PEG.generate(grammar), + rawProj = parser.parse(pbx), + project = rawProj.project; + +exports['should parse com.apple.BackgroundModes'] = function (test) { + var targets = project.attributes.TargetAttributes['1D6058900D05DD3D006BFB54'], + backgroundModes = targets.SystemCapabilities['com.apple.BackgroundModes']; + + test.deepEqual(backgroundModes, {enabled: 1}); + test.done() +} diff --git a/test/parser/file-references.js b/test/parser/file-references.js new file mode 100644 index 0000000..53f1ce3 --- /dev/null +++ b/test/parser/file-references.js @@ -0,0 +1,12 @@ +var PEG = require('pegjs'), + fs = require('fs'), + pbx = fs.readFileSync('test/parser/projects/file-references.pbxproj', 'utf-8'), + grammar = fs.readFileSync('lib/parser/pbxproj.pegjs', 'utf-8'), + parser = PEG.generate(grammar), + rawProj = parser.parse(pbx), + project = rawProj.project; + +exports['should have a PBXFileReference section'] = function (test) { + test.ok(project.objects['PBXFileReference']); + test.done(); +} diff --git a/test/parser/hash.js b/test/parser/hash.js index 9cdad4f..c64c829 100644 --- a/test/parser/hash.js +++ b/test/parser/hash.js @@ -2,7 +2,7 @@ var PEG = require('pegjs'), fs = require('fs'), pbx = fs.readFileSync('test/parser/projects/hash.pbxproj', 'utf-8'), grammar = fs.readFileSync('lib/parser/pbxproj.pegjs', 'utf-8'), - parser = PEG.buildParser(grammar), + parser = PEG.generate(grammar), rawProj = parser.parse(pbx), project = rawProj.project; diff --git a/test/parser/header-search.js b/test/parser/header-search.js index 0f34adc..5bf27fa 100644 --- a/test/parser/header-search.js +++ b/test/parser/header-search.js @@ -2,7 +2,7 @@ var PEG = require('pegjs'), fs = require('fs'), pbx = fs.readFileSync('test/parser/projects/header-search.pbxproj', 'utf-8'), grammar = fs.readFileSync('lib/parser/pbxproj.pegjs', 'utf-8'), - parser = PEG.buildParser(grammar), + parser = PEG.generate(grammar), rawProj = parser.parse(pbx), project = rawProj.project; diff --git a/test/parser/projects/dots-in-names.pbxproj b/test/parser/projects/dots-in-names.pbxproj new file mode 100644 index 0000000..43fb8a2 --- /dev/null +++ b/test/parser/projects/dots-in-names.pbxproj @@ -0,0 +1,17 @@ +// !$*UTF8*$! +{ + isa = PBXProject; + attributes = { + LastUpgradeCheck = 500; + TargetAttributes = { + 1D6058900D05DD3D006BFB54 = { + DevelopmentTeam = 9KM9BSKFZ3; + SystemCapabilities = { + com.apple.BackgroundModes = { + enabled = 1; + }; + }; + }; + }; + }; +} diff --git a/test/parser/projects/expected/with_array_expected.pbxproj b/test/parser/projects/expected/with_array_expected.pbxproj new file mode 100644 index 0000000..efa5e47 --- /dev/null +++ b/test/parser/projects/expected/with_array_expected.pbxproj @@ -0,0 +1,25 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + empties = ( + ); + ARCHS = ( + armv6, + armv7, + ); + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, + ); + LIBS = ( + "$(SRCROOT)/bestgame/libs/**", + ); + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/bestgame/libs/**", + ); + objectVersion = 45; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/test/parser/projects/file-references.pbxproj b/test/parser/projects/file-references.pbxproj index 3aa7a56..949810d 100644 --- a/test/parser/projects/file-references.pbxproj +++ b/test/parser/projects/file-references.pbxproj @@ -31,7 +31,7 @@ 3072F99613A8081B00425683 /* Capture.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Capture.bundle; path = Resources/Capture.bundle; sourceTree = ""; }; 307D28A1123043350040C0FA /* PhoneGapBuildSettings.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = PhoneGapBuildSettings.xcconfig; sourceTree = ""; }; 308D052E1370CCF300D202BF /* icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-72.png"; sourceTree = ""; }; - 308D052F1370CCF300D202BF /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = ""; }; + 308D052F1370CCF300D202BF /* 1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 1.png; sourceTree = ""; }; 308D05301370CCF300D202BF /* icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon@2x.png"; sourceTree = ""; }; 308D05341370CCF300D202BF /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 308D05351370CCF300D202BF /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; diff --git a/test/parser/projects/group.pbxproj b/test/parser/projects/group.pbxproj new file mode 100644 index 0000000..700242c --- /dev/null +++ b/test/parser/projects/group.pbxproj @@ -0,0 +1,575 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 301BF552109A68D80062928A /* libCordova.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF535109A57CC0062928A /* libCordova.a */; }; + 302D95F114D2391D003F00A1 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 302D95EF14D2391D003F00A1 /* MainViewController.m */; }; + 302D95F214D2391D003F00A1 /* MainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 302D95F014D2391D003F00A1 /* MainViewController.xib */; }; + 305D5FD1115AB8F900A74A75 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */; }; + 3088BBBD154F3926009F9C59 /* Default-Landscape@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBB7154F3926009F9C59 /* Default-Landscape@2x~ipad.png */; }; + 3088BBBE154F3926009F9C59 /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBB8154F3926009F9C59 /* Default-Landscape~ipad.png */; }; + 3088BBBF154F3926009F9C59 /* Default-Portrait@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBB9154F3926009F9C59 /* Default-Portrait@2x~ipad.png */; }; + 3088BBC0154F3926009F9C59 /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBBA154F3926009F9C59 /* Default-Portrait~ipad.png */; }; + 3088BBC1154F3926009F9C59 /* Default@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBBB154F3926009F9C59 /* Default@2x~iphone.png */; }; + 3088BBC2154F3926009F9C59 /* Default~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBBC154F3926009F9C59 /* Default~iphone.png */; }; + 308D05371370CCF300D202BF /* icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D052E1370CCF300D202BF /* icon-72.png */; }; + 308D05381370CCF300D202BF /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D052F1370CCF300D202BF /* icon.png */; }; + 308D05391370CCF300D202BF /* icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D05301370CCF300D202BF /* icon@2x.png */; }; + 30B4F30019D5E07200D9F7D8 /* Default-667h.png in Resources */ = {isa = PBXBuildFile; fileRef = 30B4F2FD19D5E07200D9F7D8 /* Default-667h.png */; }; + 30B4F30119D5E07200D9F7D8 /* Default-736h.png in Resources */ = {isa = PBXBuildFile; fileRef = 30B4F2FE19D5E07200D9F7D8 /* Default-736h.png */; }; + 30B4F30219D5E07200D9F7D8 /* Default-Landscape-736h.png in Resources */ = {isa = PBXBuildFile; fileRef = 30B4F2FF19D5E07200D9F7D8 /* Default-Landscape-736h.png */; }; + 30C1856619D5FC0A00212699 /* icon-60@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 30C1856519D5FC0A00212699 /* icon-60@3x.png */; }; + 30FC414916E50CA1004E6F35 /* icon-72@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 30FC414816E50CA1004E6F35 /* icon-72@2x.png */; }; + 5B1594DD16A7569C00FEF299 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */; }; + 7E7966DE1810823500FA85AD /* icon-40.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D41810823500FA85AD /* icon-40.png */; }; + 7E7966DF1810823500FA85AD /* icon-40@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D51810823500FA85AD /* icon-40@2x.png */; }; + 7E7966E01810823500FA85AD /* icon-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D61810823500FA85AD /* icon-50.png */; }; + 7E7966E11810823500FA85AD /* icon-50@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D71810823500FA85AD /* icon-50@2x.png */; }; + 7E7966E21810823500FA85AD /* icon-60.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D81810823500FA85AD /* icon-60.png */; }; + 7E7966E31810823500FA85AD /* icon-60@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D91810823500FA85AD /* icon-60@2x.png */; }; + 7E7966E41810823500FA85AD /* icon-76.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DA1810823500FA85AD /* icon-76.png */; }; + 7E7966E51810823500FA85AD /* icon-76@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DB1810823500FA85AD /* icon-76@2x.png */; }; + 7E7966E61810823500FA85AD /* icon-small.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DC1810823500FA85AD /* icon-small.png */; }; + 7E7966E71810823500FA85AD /* icon-small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DD1810823500FA85AD /* icon-small@2x.png */; }; + D4A0D8761607E02300AEF8BB /* Default-568h@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 301BF534109A57CC0062928A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = D2AAC07E0554694100DB518D; + remoteInfo = CordovaLib; + }; + 301BF550109A68C00062928A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = CordovaLib; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* HelloCordova.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "HelloCordova.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1F766FDD13BBADB100FB74C0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = Localizable.strings; sourceTree = ""; }; + 1F766FE013BBADB100FB74C0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = Localizable.strings; sourceTree = ""; }; + 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CordovaLib.xcodeproj; path = "CordovaLib/CordovaLib.xcodeproj"; sourceTree = ""; }; + 301BF56E109A69640062928A /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; path = www; sourceTree = SOURCE_ROOT; }; + 302D95EE14D2391D003F00A1 /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = ""; }; + 302D95EF14D2391D003F00A1 /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = ""; }; + 302D95F014D2391D003F00A1 /* MainViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainViewController.xib; sourceTree = ""; }; + 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; }; + 3088BBB7154F3926009F9C59 /* Default-Landscape@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape@2x~ipad.png"; sourceTree = ""; }; + 3088BBB8154F3926009F9C59 /* Default-Landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape~ipad.png"; sourceTree = ""; }; + 3088BBB9154F3926009F9C59 /* Default-Portrait@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait@2x~ipad.png"; sourceTree = ""; }; + 3088BBBA154F3926009F9C59 /* Default-Portrait~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait~ipad.png"; sourceTree = ""; }; + 3088BBBB154F3926009F9C59 /* Default@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x~iphone.png"; sourceTree = ""; }; + 3088BBBC154F3926009F9C59 /* Default~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default~iphone.png"; sourceTree = ""; }; + 308D052E1370CCF300D202BF /* icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-72.png"; sourceTree = ""; }; + 308D052F1370CCF300D202BF /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = ""; }; + 308D05301370CCF300D202BF /* icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon@2x.png"; sourceTree = ""; }; + 30B4F2FD19D5E07200D9F7D8 /* Default-667h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-667h.png"; sourceTree = ""; }; + 30B4F2FE19D5E07200D9F7D8 /* Default-736h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h.png"; sourceTree = ""; }; + 30B4F2FF19D5E07200D9F7D8 /* Default-Landscape-736h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape-736h.png"; sourceTree = ""; }; + 30C1856519D5FC0A00212699 /* icon-60@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-60@3x.png"; sourceTree = ""; }; + 30FC414816E50CA1004E6F35 /* icon-72@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-72@2x.png"; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* HelloCordova-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HelloCordova-Prefix.pch"; sourceTree = ""; }; + 5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; }; + 7E7966D41810823500FA85AD /* icon-40.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-40.png"; sourceTree = ""; }; + 7E7966D51810823500FA85AD /* icon-40@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-40@2x.png"; sourceTree = ""; }; + 7E7966D61810823500FA85AD /* icon-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-50.png"; sourceTree = ""; }; + 7E7966D71810823500FA85AD /* icon-50@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-50@2x.png"; sourceTree = ""; }; + 7E7966D81810823500FA85AD /* icon-60.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-60.png"; sourceTree = ""; }; + 7E7966D91810823500FA85AD /* icon-60@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-60@2x.png"; sourceTree = ""; }; + 7E7966DA1810823500FA85AD /* icon-76.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-76.png"; sourceTree = ""; }; + 7E7966DB1810823500FA85AD /* icon-76@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-76@2x.png"; sourceTree = ""; }; + 7E7966DC1810823500FA85AD /* icon-small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small.png"; sourceTree = ""; }; + 7E7966DD1810823500FA85AD /* icon-small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small@2x.png"; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* HelloCordova-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "HelloCordova-Info.plist"; path = "../HelloCordova-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x~iphone.png"; sourceTree = ""; }; + EB87FDF21871DA7A0020F90C /* merges */ = {isa = PBXFileReference; lastKnownFileType = folder; name = merges; path = ../../merges; sourceTree = ""; }; + EB87FDF31871DA8E0020F90C /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; name = www; path = ../../www; sourceTree = ""; }; + EB87FDF41871DAF40020F90C /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = config.xml; path = ../../config.xml; sourceTree = ""; }; + F840E1F0165FE0F500CFE078 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = config.xml; path = "HelloCordova/config.xml"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5B1594DD16A7569C00FEF299 /* AssetsLibrary.framework in Frameworks */, + 301BF552109A68D80062928A /* libCordova.a in Frameworks */, + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, + 305D5FD1115AB8F900A74A75 /* MobileCoreServices.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 302D95EE14D2391D003F00A1 /* MainViewController.h */, + 302D95EF14D2391D003F00A1 /* MainViewController.m */, + 302D95F014D2391D003F00A1 /* MainViewController.xib */, + 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623250D0F684500981E51 /* AppDelegate.m */, + ); + name = Classes; + path = "HelloCordova/Classes"; + sourceTree = SOURCE_ROOT; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* HelloCordova.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + EB87FDF41871DAF40020F90C /* config.xml */, + EB87FDF31871DA8E0020F90C /* www */, + EB87FDF21871DA7A0020F90C /* merges */, + EB87FDF11871DA420020F90C /* Staging */, + 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */, + 080E96DDFE201D6D7F000001 /* Classes */, + 307C750510C5A3420062BCA9 /* Plugins */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* HelloCordova-Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + path = "HelloCordova"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 308D052D1370CCF300D202BF /* icons */, + 308D05311370CCF300D202BF /* splash */, + 8D1107310486CEB800E47090 /* HelloCordova-Info.plist */, + ); + name = Resources; + path = "HelloCordova/Resources"; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */, + 288765FC0DF74451002DB57D /* CoreGraphics.framework */, + 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 301BF52E109A57CC0062928A /* Products */ = { + isa = PBXGroup; + children = ( + 301BF535109A57CC0062928A /* libCordova.a */, + ); + name = Products; + sourceTree = ""; + }; + 307C750510C5A3420062BCA9 /* Plugins */ = { + isa = PBXGroup; + children = ( + ); + name = Plugins; + path = "HelloCordova/Plugins"; + sourceTree = SOURCE_ROOT; + }; + 308D052D1370CCF300D202BF /* icons */ = { + isa = PBXGroup; + children = ( + 30C1856519D5FC0A00212699 /* icon-60@3x.png */, + 7E7966D41810823500FA85AD /* icon-40.png */, + 7E7966D51810823500FA85AD /* icon-40@2x.png */, + 7E7966D61810823500FA85AD /* icon-50.png */, + 7E7966D71810823500FA85AD /* icon-50@2x.png */, + 7E7966D81810823500FA85AD /* icon-60.png */, + 7E7966D91810823500FA85AD /* icon-60@2x.png */, + 7E7966DA1810823500FA85AD /* icon-76.png */, + 7E7966DB1810823500FA85AD /* icon-76@2x.png */, + 7E7966DC1810823500FA85AD /* icon-small.png */, + 7E7966DD1810823500FA85AD /* icon-small@2x.png */, + 30FC414816E50CA1004E6F35 /* icon-72@2x.png */, + 308D052E1370CCF300D202BF /* icon-72.png */, + 308D052F1370CCF300D202BF /* icon.png */, + 308D05301370CCF300D202BF /* icon@2x.png */, + ); + path = icons; + sourceTree = ""; + }; + 308D05311370CCF300D202BF /* splash */ = { + isa = PBXGroup; + children = ( + 30B4F2FD19D5E07200D9F7D8 /* Default-667h.png */, + 30B4F2FE19D5E07200D9F7D8 /* Default-736h.png */, + 30B4F2FF19D5E07200D9F7D8 /* Default-Landscape-736h.png */, + D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */, + 3088BBB7154F3926009F9C59 /* Default-Landscape@2x~ipad.png */, + 3088BBB8154F3926009F9C59 /* Default-Landscape~ipad.png */, + 3088BBB9154F3926009F9C59 /* Default-Portrait@2x~ipad.png */, + 3088BBBA154F3926009F9C59 /* Default-Portrait~ipad.png */, + 3088BBBB154F3926009F9C59 /* Default@2x~iphone.png */, + 3088BBBC154F3926009F9C59 /* Default~iphone.png */, + ); + path = splash; + sourceTree = ""; + }; + EB87FDF11871DA420020F90C /* Staging */ = { + isa = PBXGroup; + children = ( + F840E1F0165FE0F500CFE078 /* config.xml */, + 301BF56E109A69640062928A /* www */, + ); + name = Staging; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* HelloCordova */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "HelloCordova" */; + buildPhases = ( + 304B58A110DAC018002A0835 /* Copy www directory */, + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 301BF551109A68C00062928A /* PBXTargetDependency */, + ); + name = "HelloCordova"; + productName = "HelloCordova"; + productReference = 1D6058910D05DD3D006BFB54 /* HelloCordova.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0510; + }; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "__CLI__" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + es, + de, + se, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 301BF52E109A57CC0062928A /* Products */; + ProjectRef = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* HelloCordova */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 301BF535109A57CC0062928A /* libCordova.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libCordova.a; + remoteRef = 301BF534109A57CC0062928A /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7E7966E41810823500FA85AD /* icon-76.png in Resources */, + 7E7966DF1810823500FA85AD /* icon-40@2x.png in Resources */, + 308D05371370CCF300D202BF /* icon-72.png in Resources */, + 30B4F30119D5E07200D9F7D8 /* Default-736h.png in Resources */, + 308D05381370CCF300D202BF /* icon.png in Resources */, + 308D05391370CCF300D202BF /* icon@2x.png in Resources */, + 302D95F214D2391D003F00A1 /* MainViewController.xib in Resources */, + 7E7966E01810823500FA85AD /* icon-50.png in Resources */, + 7E7966E31810823500FA85AD /* icon-60@2x.png in Resources */, + 7E7966E61810823500FA85AD /* icon-small.png in Resources */, + 3088BBBD154F3926009F9C59 /* Default-Landscape@2x~ipad.png in Resources */, + 3088BBBE154F3926009F9C59 /* Default-Landscape~ipad.png in Resources */, + 3088BBBF154F3926009F9C59 /* Default-Portrait@2x~ipad.png in Resources */, + 7E7966E71810823500FA85AD /* icon-small@2x.png in Resources */, + 3088BBC0154F3926009F9C59 /* Default-Portrait~ipad.png in Resources */, + 30B4F30019D5E07200D9F7D8 /* Default-667h.png in Resources */, + 7E7966DE1810823500FA85AD /* icon-40.png in Resources */, + 3088BBC1154F3926009F9C59 /* Default@2x~iphone.png in Resources */, + 7E7966E21810823500FA85AD /* icon-60.png in Resources */, + 3088BBC2154F3926009F9C59 /* Default~iphone.png in Resources */, + D4A0D8761607E02300AEF8BB /* Default-568h@2x~iphone.png in Resources */, + 30B4F30219D5E07200D9F7D8 /* Default-Landscape-736h.png in Resources */, + 30C1856619D5FC0A00212699 /* icon-60@3x.png in Resources */, + 7E7966E11810823500FA85AD /* icon-50@2x.png in Resources */, + 7E7966E51810823500FA85AD /* icon-76@2x.png in Resources */, + 30FC414916E50CA1004E6F35 /* icon-72@2x.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 304B58A110DAC018002A0835 /* Copy www directory */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Copy www directory"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cordova/lib/copy-www-build-step.sh"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, + 302D95F114D2391D003F00A1 /* MainViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 301BF551109A68C00062928A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CordovaLib; + targetProxy = 301BF550109A68C00062928A /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_OBJC_ARC = YES; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "HelloCordova/HelloCordova-Prefix.pch"; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = ""; + INFOPLIST_FILE = "HelloCordova/HelloCordova-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + OTHER_LDFLAGS = ( + "-weak_framework", + CoreFoundation, + "-weak_framework", + UIKit, + "-weak_framework", + AVFoundation, + "-weak_framework", + CoreMedia, + "-weak-lSystem", + "-ObjC", + ); + PRODUCT_NAME = "HelloCordova"; + TARGETED_DEVICE_FAMILY = "1"; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_OBJC_ARC = YES; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "HelloCordova/HelloCordova-Prefix.pch"; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = ""; + INFOPLIST_FILE = "HelloCordova/HelloCordova-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + OTHER_LDFLAGS = ( + "-weak_framework", + CoreFoundation, + "-weak_framework", + UIKit, + "-weak_framework", + AVFoundation, + "-weak_framework", + CoreMedia, + "-weak-lSystem", + "-ObjC", + ); + PRODUCT_NAME = "HelloCordova"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = ""; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"", + "\"$(OBJROOT)/UninstalledProducts/include\"", + "\"$(BUILT_PRODUCTS_DIR)\"", + ); + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = ( + "-weak_framework", + CoreFoundation, + "-weak_framework", + UIKit, + "-weak_framework", + AVFoundation, + "-weak_framework", + CoreMedia, + "-weak-lSystem", + "-ObjC", + ); + SDKROOT = iphoneos; + SKIP_INSTALL = NO; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = ""; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"", + "\"$(OBJROOT)/UninstalledProducts/include\"", + "\"$(BUILT_PRODUCTS_DIR)\"", + ); + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + OTHER_LDFLAGS = ( + "-weak_framework", + CoreFoundation, + "-weak_framework", + UIKit, + "-weak_framework", + AVFoundation, + "-weak_framework", + CoreMedia, + "-weak-lSystem", + "-ObjC", + ); + SDKROOT = iphoneos; + SKIP_INSTALL = NO; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "HelloCordova" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "__CLI__" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/test/parser/projects/library-search-paths.pbxproj b/test/parser/projects/library-search-paths.pbxproj new file mode 100644 index 0000000..3270de9 --- /dev/null +++ b/test/parser/projects/library-search-paths.pbxproj @@ -0,0 +1,500 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + B9E76573180BDDA800888C06 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9E76572180BDDA800888C06 /* Foundation.framework */; }; + B9E76575180BDDA800888C06 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9E76574180BDDA800888C06 /* CoreGraphics.framework */; }; + B9E76577180BDDA800888C06 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9E76576180BDDA800888C06 /* UIKit.framework */; }; + B9E7657D180BDDA800888C06 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = B9E7657B180BDDA800888C06 /* InfoPlist.strings */; }; + B9E7657F180BDDA800888C06 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B9E7657E180BDDA800888C06 /* main.m */; }; + B9E76583180BDDA800888C06 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B9E76582180BDDA800888C06 /* AppDelegate.m */; }; + B9E76586180BDDA800888C06 /* Main_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B9E76584180BDDA800888C06 /* Main_iPhone.storyboard */; }; + B9E76589180BDDA800888C06 /* Main_iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B9E76587180BDDA800888C06 /* Main_iPad.storyboard */; }; + B9E7658C180BDDA800888C06 /* MasterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B9E7658B180BDDA800888C06 /* MasterViewController.m */; }; + B9E7658F180BDDA800888C06 /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B9E7658E180BDDA800888C06 /* DetailViewController.m */; }; + B9E76591180BDDA800888C06 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B9E76590180BDDA800888C06 /* Images.xcassets */; }; + B9E76598180BDDA800888C06 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9E76597180BDDA800888C06 /* XCTest.framework */; }; + B9E76599180BDDA800888C06 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9E76572180BDDA800888C06 /* Foundation.framework */; }; + B9E7659A180BDDA800888C06 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9E76576180BDDA800888C06 /* UIKit.framework */; }; + B9E765A2180BDDA800888C06 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = B9E765A0180BDDA800888C06 /* InfoPlist.strings */; }; + B9E765A4180BDDA800888C06 /* testTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B9E765A3180BDDA800888C06 /* testTests.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + B9E7659B180BDDA800888C06 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = B9E76567180BDDA800888C06 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B9E7656E180BDDA800888C06; + remoteInfo = test; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + B9E7656F180BDDA800888C06 /* test.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = test.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B9E76572180BDDA800888C06 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + B9E76574180BDDA800888C06 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + B9E76576180BDDA800888C06 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + B9E7657A180BDDA800888C06 /* test-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "test-Info.plist"; sourceTree = ""; }; + B9E7657C180BDDA800888C06 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + B9E7657E180BDDA800888C06 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + B9E76580180BDDA800888C06 /* test-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "test-Prefix.pch"; sourceTree = ""; }; + B9E76581180BDDA800888C06 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + B9E76582180BDDA800888C06 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + B9E76585180BDDA800888C06 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPhone.storyboard; sourceTree = ""; }; + B9E76588180BDDA800888C06 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPad.storyboard; sourceTree = ""; }; + B9E7658A180BDDA800888C06 /* MasterViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MasterViewController.h; sourceTree = ""; }; + B9E7658B180BDDA800888C06 /* MasterViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MasterViewController.m; sourceTree = ""; }; + B9E7658D180BDDA800888C06 /* DetailViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = ""; }; + B9E7658E180BDDA800888C06 /* DetailViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DetailViewController.m; sourceTree = ""; }; + B9E76590180BDDA800888C06 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + B9E76596180BDDA800888C06 /* testTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = testTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + B9E76597180BDDA800888C06 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + B9E7659F180BDDA800888C06 /* testTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "testTests-Info.plist"; sourceTree = ""; }; + B9E765A1180BDDA800888C06 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + B9E765A3180BDDA800888C06 /* testTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = testTests.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + B9E7656C180BDDA800888C06 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B9E76575180BDDA800888C06 /* CoreGraphics.framework in Frameworks */, + B9E76577180BDDA800888C06 /* UIKit.framework in Frameworks */, + B9E76573180BDDA800888C06 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B9E76593180BDDA800888C06 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B9E76598180BDDA800888C06 /* XCTest.framework in Frameworks */, + B9E7659A180BDDA800888C06 /* UIKit.framework in Frameworks */, + B9E76599180BDDA800888C06 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + B9E76566180BDDA800888C06 = { + isa = PBXGroup; + children = ( + B9E76578180BDDA800888C06 /* test */, + B9E7659D180BDDA800888C06 /* testTests */, + B9E76571180BDDA800888C06 /* Frameworks */, + B9E76570180BDDA800888C06 /* Products */, + ); + sourceTree = ""; + }; + B9E76570180BDDA800888C06 /* Products */ = { + isa = PBXGroup; + children = ( + B9E7656F180BDDA800888C06 /* test.app */, + B9E76596180BDDA800888C06 /* testTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + B9E76571180BDDA800888C06 /* Frameworks */ = { + isa = PBXGroup; + children = ( + B9E76572180BDDA800888C06 /* Foundation.framework */, + B9E76574180BDDA800888C06 /* CoreGraphics.framework */, + B9E76576180BDDA800888C06 /* UIKit.framework */, + B9E76597180BDDA800888C06 /* XCTest.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + B9E76578180BDDA800888C06 /* test */ = { + isa = PBXGroup; + children = ( + B9E76581180BDDA800888C06 /* AppDelegate.h */, + B9E76582180BDDA800888C06 /* AppDelegate.m */, + B9E76584180BDDA800888C06 /* Main_iPhone.storyboard */, + B9E76587180BDDA800888C06 /* Main_iPad.storyboard */, + B9E7658A180BDDA800888C06 /* MasterViewController.h */, + B9E7658B180BDDA800888C06 /* MasterViewController.m */, + B9E7658D180BDDA800888C06 /* DetailViewController.h */, + B9E7658E180BDDA800888C06 /* DetailViewController.m */, + B9E76590180BDDA800888C06 /* Images.xcassets */, + B9E76579180BDDA800888C06 /* Supporting Files */, + ); + path = test; + sourceTree = ""; + }; + B9E76579180BDDA800888C06 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + B9E7657A180BDDA800888C06 /* test-Info.plist */, + B9E7657B180BDDA800888C06 /* InfoPlist.strings */, + B9E7657E180BDDA800888C06 /* main.m */, + B9E76580180BDDA800888C06 /* test-Prefix.pch */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + B9E7659D180BDDA800888C06 /* testTests */ = { + isa = PBXGroup; + children = ( + B9E765A3180BDDA800888C06 /* testTests.m */, + B9E7659E180BDDA800888C06 /* Supporting Files */, + ); + path = testTests; + sourceTree = ""; + }; + B9E7659E180BDDA800888C06 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + B9E7659F180BDDA800888C06 /* testTests-Info.plist */, + B9E765A0180BDDA800888C06 /* InfoPlist.strings */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + B9E7656E180BDDA800888C06 /* test */ = { + isa = PBXNativeTarget; + buildConfigurationList = B9E765A7180BDDA800888C06 /* Build configuration list for PBXNativeTarget "test" */; + buildPhases = ( + B9E7656B180BDDA800888C06 /* Sources */, + B9E7656C180BDDA800888C06 /* Frameworks */, + B9E7656D180BDDA800888C06 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = test; + productName = test; + productReference = B9E7656F180BDDA800888C06 /* test.app */; + productType = "com.apple.product-type.application"; + }; + B9E76595180BDDA800888C06 /* testTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = B9E765AA180BDDA800888C06 /* Build configuration list for PBXNativeTarget "testTests" */; + buildPhases = ( + B9E76592180BDDA800888C06 /* Sources */, + B9E76593180BDDA800888C06 /* Frameworks */, + B9E76594180BDDA800888C06 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + B9E7659C180BDDA800888C06 /* PBXTargetDependency */, + ); + name = testTests; + productName = testTests; + productReference = B9E76596180BDDA800888C06 /* testTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + B9E76567180BDDA800888C06 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0500; + ORGANIZATIONNAME = Cordova; + TargetAttributes = { + B9E76595180BDDA800888C06 = { + TestTargetID = B9E7656E180BDDA800888C06; + }; + }; + }; + buildConfigurationList = B9E7656A180BDDA800888C06 /* Build configuration list for PBXProject "test" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = B9E76566180BDDA800888C06; + productRefGroup = B9E76570180BDDA800888C06 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B9E7656E180BDDA800888C06 /* test */, + B9E76595180BDDA800888C06 /* testTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + B9E7656D180BDDA800888C06 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B9E76589180BDDA800888C06 /* Main_iPad.storyboard in Resources */, + B9E76591180BDDA800888C06 /* Images.xcassets in Resources */, + B9E76586180BDDA800888C06 /* Main_iPhone.storyboard in Resources */, + B9E7657D180BDDA800888C06 /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B9E76594180BDDA800888C06 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B9E765A2180BDDA800888C06 /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + B9E7656B180BDDA800888C06 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B9E76583180BDDA800888C06 /* AppDelegate.m in Sources */, + B9E7658C180BDDA800888C06 /* MasterViewController.m in Sources */, + B9E7657F180BDDA800888C06 /* main.m in Sources */, + B9E7658F180BDDA800888C06 /* DetailViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B9E76592180BDDA800888C06 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B9E765A4180BDDA800888C06 /* testTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + B9E7659C180BDDA800888C06 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B9E7656E180BDDA800888C06 /* test */; + targetProxy = B9E7659B180BDDA800888C06 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + B9E7657B180BDDA800888C06 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + B9E7657C180BDDA800888C06 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + B9E76584180BDDA800888C06 /* Main_iPhone.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B9E76585180BDDA800888C06 /* Base */, + ); + name = Main_iPhone.storyboard; + sourceTree = ""; + }; + B9E76587180BDDA800888C06 /* Main_iPad.storyboard */ = { + isa = PBXVariantGroup; + children = ( + B9E76588180BDDA800888C06 /* Base */, + ); + name = Main_iPad.storyboard; + sourceTree = ""; + }; + B9E765A0180BDDA800888C06 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + B9E765A1180BDDA800888C06 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + B9E765A5180BDDA800888C06 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B9E765A6180BDDA800888C06 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + B9E765A8180BDDA800888C06 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "test/test-Prefix.pch"; + INFOPLIST_FILE = "test/test-Info.plist"; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + B9E765A9180BDDA800888C06 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "test/test-Prefix.pch"; + INFOPLIST_FILE = "test/test-Info.plist"; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + B9E765AB180BDDA800888C06 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/test.app/test"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "test/test-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = "testTests/testTests-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUNDLE_LOADER)"; + WRAPPER_EXTENSION = xctest; + }; + name = Debug; + }; + B9E765AC180BDDA800888C06 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/test.app/test"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "test/test-Prefix.pch"; + INFOPLIST_FILE = "testTests/testTests-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUNDLE_LOADER)"; + WRAPPER_EXTENSION = xctest; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + B9E7656A180BDDA800888C06 /* Build configuration list for PBXProject "test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B9E765A5180BDDA800888C06 /* Debug */, + B9E765A6180BDDA800888C06 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B9E765A7180BDDA800888C06 /* Build configuration list for PBXNativeTarget "test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B9E765A8180BDDA800888C06 /* Debug */, + B9E765A9180BDDA800888C06 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; + B9E765AA180BDDA800888C06 /* Build configuration list for PBXNativeTarget "testTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B9E765AB180BDDA800888C06 /* Debug */, + B9E765AC180BDDA800888C06 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = B9E76567180BDDA800888C06 /* Project object */; +} + diff --git a/test/parser/projects/section-split.pbxproj b/test/parser/projects/section-split.pbxproj new file mode 100644 index 0000000..7b7f2df --- /dev/null +++ b/test/parser/projects/section-split.pbxproj @@ -0,0 +1,25 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; + objects = { +/* Begin PBXTargetDependency section */ + 301BF551109A68C00062928A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PhoneGapLib; + targetProxy = 301BF550109A68C00062928A /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXTargetDependency section */ + 45FDD1944D304A9F96DF3AC6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SecondLib; + targetProxy = 301BF550109A68C00062928A /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + }; +} diff --git a/test/parser/projects/variantgroup.pbxproj b/test/parser/projects/variantgroup.pbxproj new file mode 100644 index 0000000..0e7eac2 --- /dev/null +++ b/test/parser/projects/variantgroup.pbxproj @@ -0,0 +1,589 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 301BF552109A68D80062928A /* libCordova.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF535109A57CC0062928A /* libCordova.a */; }; + 302D95F114D2391D003F00A1 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 302D95EF14D2391D003F00A1 /* MainViewController.m */; }; + 302D95F214D2391D003F00A1 /* MainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 302D95F014D2391D003F00A1 /* MainViewController.xib */; }; + 305D5FD1115AB8F900A74A75 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */; }; + 3088BBBD154F3926009F9C59 /* Default-Landscape@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBB7154F3926009F9C59 /* Default-Landscape@2x~ipad.png */; }; + 3088BBBE154F3926009F9C59 /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBB8154F3926009F9C59 /* Default-Landscape~ipad.png */; }; + 3088BBBF154F3926009F9C59 /* Default-Portrait@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBB9154F3926009F9C59 /* Default-Portrait@2x~ipad.png */; }; + 3088BBC0154F3926009F9C59 /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBBA154F3926009F9C59 /* Default-Portrait~ipad.png */; }; + 3088BBC1154F3926009F9C59 /* Default@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBBB154F3926009F9C59 /* Default@2x~iphone.png */; }; + 3088BBC2154F3926009F9C59 /* Default~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBBC154F3926009F9C59 /* Default~iphone.png */; }; + 308D05371370CCF300D202BF /* icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D052E1370CCF300D202BF /* icon-72.png */; }; + 308D05381370CCF300D202BF /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D052F1370CCF300D202BF /* icon.png */; }; + 308D05391370CCF300D202BF /* icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D05301370CCF300D202BF /* icon@2x.png */; }; + 30B4F30019D5E07200D9F7D8 /* Default-667h.png in Resources */ = {isa = PBXBuildFile; fileRef = 30B4F2FD19D5E07200D9F7D8 /* Default-667h.png */; }; + 30B4F30119D5E07200D9F7D8 /* Default-736h.png in Resources */ = {isa = PBXBuildFile; fileRef = 30B4F2FE19D5E07200D9F7D8 /* Default-736h.png */; }; + 30B4F30219D5E07200D9F7D8 /* Default-Landscape-736h.png in Resources */ = {isa = PBXBuildFile; fileRef = 30B4F2FF19D5E07200D9F7D8 /* Default-Landscape-736h.png */; }; + 30C1856619D5FC0A00212699 /* icon-60@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 30C1856519D5FC0A00212699 /* icon-60@3x.png */; }; + 30FC414916E50CA1004E6F35 /* icon-72@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 30FC414816E50CA1004E6F35 /* icon-72@2x.png */; }; + 5B1594DD16A7569C00FEF299 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */; }; + 7E7966DE1810823500FA85AD /* icon-40.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D41810823500FA85AD /* icon-40.png */; }; + 7E7966DF1810823500FA85AD /* icon-40@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D51810823500FA85AD /* icon-40@2x.png */; }; + 7E7966E01810823500FA85AD /* icon-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D61810823500FA85AD /* icon-50.png */; }; + 7E7966E11810823500FA85AD /* icon-50@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D71810823500FA85AD /* icon-50@2x.png */; }; + 7E7966E21810823500FA85AD /* icon-60.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D81810823500FA85AD /* icon-60.png */; }; + 7E7966E31810823500FA85AD /* icon-60@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966D91810823500FA85AD /* icon-60@2x.png */; }; + 7E7966E41810823500FA85AD /* icon-76.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DA1810823500FA85AD /* icon-76.png */; }; + 7E7966E51810823500FA85AD /* icon-76@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DB1810823500FA85AD /* icon-76@2x.png */; }; + 7E7966E61810823500FA85AD /* icon-small.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DC1810823500FA85AD /* icon-small.png */; }; + 7E7966E71810823500FA85AD /* icon-small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DD1810823500FA85AD /* icon-small@2x.png */; }; + D4A0D8761607E02300AEF8BB /* Default-568h@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */; }; + 07E3BDBD1DF1DEA500E49912 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 07E3BDBF1DF1DEAF00E49912 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = ""; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 301BF534109A57CC0062928A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = D2AAC07E0554694100DB518D; + remoteInfo = CordovaLib; + }; + 301BF550109A68C00062928A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = CordovaLib; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* HelloCordova.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "HelloCordova.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1F766FDD13BBADB100FB74C0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = Localizable.strings; sourceTree = ""; }; + 1F766FE013BBADB100FB74C0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = Localizable.strings; sourceTree = ""; }; + 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CordovaLib.xcodeproj; path = "CordovaLib/CordovaLib.xcodeproj"; sourceTree = ""; }; + 301BF56E109A69640062928A /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; path = www; sourceTree = SOURCE_ROOT; }; + 302D95EE14D2391D003F00A1 /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = ""; }; + 302D95EF14D2391D003F00A1 /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = ""; }; + 302D95F014D2391D003F00A1 /* MainViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainViewController.xib; sourceTree = ""; }; + 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; }; + 3088BBB7154F3926009F9C59 /* Default-Landscape@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape@2x~ipad.png"; sourceTree = ""; }; + 3088BBB8154F3926009F9C59 /* Default-Landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape~ipad.png"; sourceTree = ""; }; + 3088BBB9154F3926009F9C59 /* Default-Portrait@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait@2x~ipad.png"; sourceTree = ""; }; + 3088BBBA154F3926009F9C59 /* Default-Portrait~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait~ipad.png"; sourceTree = ""; }; + 3088BBBB154F3926009F9C59 /* Default@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x~iphone.png"; sourceTree = ""; }; + 3088BBBC154F3926009F9C59 /* Default~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default~iphone.png"; sourceTree = ""; }; + 308D052E1370CCF300D202BF /* icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-72.png"; sourceTree = ""; }; + 308D052F1370CCF300D202BF /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = ""; }; + 308D05301370CCF300D202BF /* icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon@2x.png"; sourceTree = ""; }; + 30B4F2FD19D5E07200D9F7D8 /* Default-667h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-667h.png"; sourceTree = ""; }; + 30B4F2FE19D5E07200D9F7D8 /* Default-736h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h.png"; sourceTree = ""; }; + 30B4F2FF19D5E07200D9F7D8 /* Default-Landscape-736h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape-736h.png"; sourceTree = ""; }; + 30C1856519D5FC0A00212699 /* icon-60@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-60@3x.png"; sourceTree = ""; }; + 30FC414816E50CA1004E6F35 /* icon-72@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-72@2x.png"; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* HelloCordova-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HelloCordova-Prefix.pch"; sourceTree = ""; }; + 5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; }; + 7E7966D41810823500FA85AD /* icon-40.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-40.png"; sourceTree = ""; }; + 7E7966D51810823500FA85AD /* icon-40@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-40@2x.png"; sourceTree = ""; }; + 7E7966D61810823500FA85AD /* icon-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-50.png"; sourceTree = ""; }; + 7E7966D71810823500FA85AD /* icon-50@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-50@2x.png"; sourceTree = ""; }; + 7E7966D81810823500FA85AD /* icon-60.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-60.png"; sourceTree = ""; }; + 7E7966D91810823500FA85AD /* icon-60@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-60@2x.png"; sourceTree = ""; }; + 7E7966DA1810823500FA85AD /* icon-76.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-76.png"; sourceTree = ""; }; + 7E7966DB1810823500FA85AD /* icon-76@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-76@2x.png"; sourceTree = ""; }; + 7E7966DC1810823500FA85AD /* icon-small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small.png"; sourceTree = ""; }; + 7E7966DD1810823500FA85AD /* icon-small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small@2x.png"; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* HelloCordova-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "HelloCordova-Info.plist"; path = "../HelloCordova-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x~iphone.png"; sourceTree = ""; }; + EB87FDF21871DA7A0020F90C /* merges */ = {isa = PBXFileReference; lastKnownFileType = folder; name = merges; path = ../../merges; sourceTree = ""; }; + EB87FDF31871DA8E0020F90C /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; name = www; path = ../../www; sourceTree = ""; }; + EB87FDF41871DAF40020F90C /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = config.xml; path = ../../config.xml; sourceTree = ""; }; + F840E1F0165FE0F500CFE078 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = config.xml; path = "HelloCordova/config.xml"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5B1594DD16A7569C00FEF299 /* AssetsLibrary.framework in Frameworks */, + 301BF552109A68D80062928A /* libCordova.a in Frameworks */, + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, + 305D5FD1115AB8F900A74A75 /* MobileCoreServices.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 302D95EE14D2391D003F00A1 /* MainViewController.h */, + 302D95EF14D2391D003F00A1 /* MainViewController.m */, + 302D95F014D2391D003F00A1 /* MainViewController.xib */, + 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623250D0F684500981E51 /* AppDelegate.m */, + ); + name = Classes; + path = "HelloCordova/Classes"; + sourceTree = SOURCE_ROOT; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* HelloCordova.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + EB87FDF41871DAF40020F90C /* config.xml */, + EB87FDF31871DA8E0020F90C /* www */, + EB87FDF21871DA7A0020F90C /* merges */, + EB87FDF11871DA420020F90C /* Staging */, + 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */, + 080E96DDFE201D6D7F000001 /* Classes */, + 307C750510C5A3420062BCA9 /* Plugins */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* HelloCordova-Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + path = "HelloCordova"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 308D052D1370CCF300D202BF /* icons */, + 308D05311370CCF300D202BF /* splash */, + 8D1107310486CEB800E47090 /* HelloCordova-Info.plist */, + ); + name = Resources; + path = "HelloCordova/Resources"; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */, + 288765FC0DF74451002DB57D /* CoreGraphics.framework */, + 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 301BF52E109A57CC0062928A /* Products */ = { + isa = PBXGroup; + children = ( + 301BF535109A57CC0062928A /* libCordova.a */, + ); + name = Products; + sourceTree = ""; + }; + 307C750510C5A3420062BCA9 /* Plugins */ = { + isa = PBXGroup; + children = ( + ); + name = Plugins; + path = "HelloCordova/Plugins"; + sourceTree = SOURCE_ROOT; + }; + 308D052D1370CCF300D202BF /* icons */ = { + isa = PBXGroup; + children = ( + 30C1856519D5FC0A00212699 /* icon-60@3x.png */, + 7E7966D41810823500FA85AD /* icon-40.png */, + 7E7966D51810823500FA85AD /* icon-40@2x.png */, + 7E7966D61810823500FA85AD /* icon-50.png */, + 7E7966D71810823500FA85AD /* icon-50@2x.png */, + 7E7966D81810823500FA85AD /* icon-60.png */, + 7E7966D91810823500FA85AD /* icon-60@2x.png */, + 7E7966DA1810823500FA85AD /* icon-76.png */, + 7E7966DB1810823500FA85AD /* icon-76@2x.png */, + 7E7966DC1810823500FA85AD /* icon-small.png */, + 7E7966DD1810823500FA85AD /* icon-small@2x.png */, + 30FC414816E50CA1004E6F35 /* icon-72@2x.png */, + 308D052E1370CCF300D202BF /* icon-72.png */, + 308D052F1370CCF300D202BF /* icon.png */, + 308D05301370CCF300D202BF /* icon@2x.png */, + ); + path = icons; + sourceTree = ""; + }; + 308D05311370CCF300D202BF /* splash */ = { + isa = PBXGroup; + children = ( + 30B4F2FD19D5E07200D9F7D8 /* Default-667h.png */, + 30B4F2FE19D5E07200D9F7D8 /* Default-736h.png */, + 30B4F2FF19D5E07200D9F7D8 /* Default-Landscape-736h.png */, + D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */, + 3088BBB7154F3926009F9C59 /* Default-Landscape@2x~ipad.png */, + 3088BBB8154F3926009F9C59 /* Default-Landscape~ipad.png */, + 3088BBB9154F3926009F9C59 /* Default-Portrait@2x~ipad.png */, + 3088BBBA154F3926009F9C59 /* Default-Portrait~ipad.png */, + 3088BBBB154F3926009F9C59 /* Default@2x~iphone.png */, + 3088BBBC154F3926009F9C59 /* Default~iphone.png */, + ); + path = splash; + sourceTree = ""; + }; + EB87FDF11871DA420020F90C /* Staging */ = { + isa = PBXGroup; + children = ( + F840E1F0165FE0F500CFE078 /* config.xml */, + 301BF56E109A69640062928A /* www */, + ); + name = Staging; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXVariantGroup section */ +07E3BDBC1DF1DEA500E49912 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 07E3BDBD1DF1DEA500E49912 /* en */, + 07E3BDBF1DF1DEAF00E49912 /* ja */, + ); + name = Localizable.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* HelloCordova */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "HelloCordova" */; + buildPhases = ( + 304B58A110DAC018002A0835 /* Copy www directory */, + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 301BF551109A68C00062928A /* PBXTargetDependency */, + ); + name = "HelloCordova"; + productName = "HelloCordova"; + productReference = 1D6058910D05DD3D006BFB54 /* HelloCordova.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0510; + }; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "__CLI__" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + es, + de, + se, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 301BF52E109A57CC0062928A /* Products */; + ProjectRef = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* HelloCordova */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 301BF535109A57CC0062928A /* libCordova.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libCordova.a; + remoteRef = 301BF534109A57CC0062928A /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7E7966E41810823500FA85AD /* icon-76.png in Resources */, + 7E7966DF1810823500FA85AD /* icon-40@2x.png in Resources */, + 308D05371370CCF300D202BF /* icon-72.png in Resources */, + 30B4F30119D5E07200D9F7D8 /* Default-736h.png in Resources */, + 308D05381370CCF300D202BF /* icon.png in Resources */, + 308D05391370CCF300D202BF /* icon@2x.png in Resources */, + 302D95F214D2391D003F00A1 /* MainViewController.xib in Resources */, + 7E7966E01810823500FA85AD /* icon-50.png in Resources */, + 7E7966E31810823500FA85AD /* icon-60@2x.png in Resources */, + 7E7966E61810823500FA85AD /* icon-small.png in Resources */, + 3088BBBD154F3926009F9C59 /* Default-Landscape@2x~ipad.png in Resources */, + 3088BBBE154F3926009F9C59 /* Default-Landscape~ipad.png in Resources */, + 3088BBBF154F3926009F9C59 /* Default-Portrait@2x~ipad.png in Resources */, + 7E7966E71810823500FA85AD /* icon-small@2x.png in Resources */, + 3088BBC0154F3926009F9C59 /* Default-Portrait~ipad.png in Resources */, + 30B4F30019D5E07200D9F7D8 /* Default-667h.png in Resources */, + 7E7966DE1810823500FA85AD /* icon-40.png in Resources */, + 3088BBC1154F3926009F9C59 /* Default@2x~iphone.png in Resources */, + 7E7966E21810823500FA85AD /* icon-60.png in Resources */, + 3088BBC2154F3926009F9C59 /* Default~iphone.png in Resources */, + D4A0D8761607E02300AEF8BB /* Default-568h@2x~iphone.png in Resources */, + 30B4F30219D5E07200D9F7D8 /* Default-Landscape-736h.png in Resources */, + 30C1856619D5FC0A00212699 /* icon-60@3x.png in Resources */, + 7E7966E11810823500FA85AD /* icon-50@2x.png in Resources */, + 7E7966E51810823500FA85AD /* icon-76@2x.png in Resources */, + 30FC414916E50CA1004E6F35 /* icon-72@2x.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 304B58A110DAC018002A0835 /* Copy www directory */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Copy www directory"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cordova/lib/copy-www-build-step.sh"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, + 302D95F114D2391D003F00A1 /* MainViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 301BF551109A68C00062928A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CordovaLib; + targetProxy = 301BF550109A68C00062928A /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_OBJC_ARC = YES; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "HelloCordova/HelloCordova-Prefix.pch"; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = ""; + INFOPLIST_FILE = "HelloCordova/HelloCordova-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + OTHER_LDFLAGS = ( + "-weak_framework", + CoreFoundation, + "-weak_framework", + UIKit, + "-weak_framework", + AVFoundation, + "-weak_framework", + CoreMedia, + "-weak-lSystem", + "-ObjC", + ); + PRODUCT_NAME = "HelloCordova"; + TARGETED_DEVICE_FAMILY = "1"; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_OBJC_ARC = YES; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "HelloCordova/HelloCordova-Prefix.pch"; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = ""; + INFOPLIST_FILE = "HelloCordova/HelloCordova-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + OTHER_LDFLAGS = ( + "-weak_framework", + CoreFoundation, + "-weak_framework", + UIKit, + "-weak_framework", + AVFoundation, + "-weak_framework", + CoreMedia, + "-weak-lSystem", + "-ObjC", + ); + PRODUCT_NAME = "HelloCordova"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = ""; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"", + "\"$(OBJROOT)/UninstalledProducts/include\"", + "\"$(BUILT_PRODUCTS_DIR)\"", + ); + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = ( + "-weak_framework", + CoreFoundation, + "-weak_framework", + UIKit, + "-weak_framework", + AVFoundation, + "-weak_framework", + CoreMedia, + "-weak-lSystem", + "-ObjC", + ); + SDKROOT = iphoneos; + SKIP_INSTALL = NO; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_THUMB_SUPPORT = NO; + GCC_VERSION = ""; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"", + "\"$(OBJROOT)/UninstalledProducts/include\"", + "\"$(BUILT_PRODUCTS_DIR)\"", + ); + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + OTHER_LDFLAGS = ( + "-weak_framework", + CoreFoundation, + "-weak_framework", + UIKit, + "-weak_framework", + AVFoundation, + "-weak_framework", + CoreMedia, + "-weak-lSystem", + "-ObjC", + ); + SDKROOT = iphoneos; + SKIP_INSTALL = NO; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "HelloCordova" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "__CLI__" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/test/parser/projects/with_array.pbxproj b/test/parser/projects/with_array.pbxproj index bdd7247..2c876f2 100644 --- a/test/parser/projects/with_array.pbxproj +++ b/test/parser/projects/with_array.pbxproj @@ -13,6 +13,13 @@ 1D60589B0D05DD56006BFB54 /* main.m in Sources */, 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, ); + LIBS = ( + "$(SRCROOT)/bestgame/libs/**" + ); + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/bestgame/libs/**" + ); objectVersion = 45; rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; } diff --git a/test/parser/section-entries.js b/test/parser/section-entries.js index 7c54fef..86fc506 100644 --- a/test/parser/section-entries.js +++ b/test/parser/section-entries.js @@ -2,7 +2,7 @@ var PEG = require('pegjs'), fs = require('fs'), pbx = fs.readFileSync('test/parser/projects/section-entries.pbxproj', 'utf-8'), grammar = fs.readFileSync('lib/parser/pbxproj.pegjs', 'utf-8'), - parser = PEG.buildParser(grammar), + parser = PEG.generate(grammar), rawProj = parser.parse(pbx), project = rawProj.project; diff --git a/test/parser/section-split.js b/test/parser/section-split.js new file mode 100644 index 0000000..aa6ebdd --- /dev/null +++ b/test/parser/section-split.js @@ -0,0 +1,35 @@ +var PEG = require('pegjs'), + fs = require('fs'), + pbx = fs.readFileSync('test/parser/projects/section-split.pbxproj', 'utf-8'), + grammar = fs.readFileSync('lib/parser/pbxproj.pegjs', 'utf-8'), + parser = PEG.generate(grammar), + rawProj = parser.parse(pbx), + project = rawProj.project; + +exports['should have a PBXTargetDependency section'] = function (test) { + test.ok(project.objects['PBXTargetDependency']); + test.done(); +} + +exports['should have the right child of PBXTargetDependency section'] = function (test) { + test.ok(project.objects['PBXTargetDependency']['301BF551109A68C00062928A']); + test.done(); +} + +exports['should have the right properties on the dependency'] = function (test) { + var dependency = project.objects['PBXTargetDependency']['301BF551109A68C00062928A']; + + test.equal(dependency.isa, 'PBXTargetDependency') + test.equal(dependency.name, 'PhoneGapLib') + test.equal(dependency.targetProxy, '301BF550109A68C00062928A') + test.equal(dependency['targetProxy_comment'], 'PBXContainerItemProxy') + + test.done(); +} + +exports['should merge two PBXTargetDependency sections'] = function (test) { + test.ok(project.objects['PBXTargetDependency']['301BF551109A68C00062928A']); + test.ok(project.objects['PBXTargetDependency']['45FDD1944D304A9F96DF3AC6']); + test.done(); +} + diff --git a/test/parser/section.js b/test/parser/section.js index afe6f61..a49474d 100644 --- a/test/parser/section.js +++ b/test/parser/section.js @@ -2,7 +2,7 @@ var PEG = require('pegjs'), fs = require('fs'), pbx = fs.readFileSync('test/parser/projects/section.pbxproj', 'utf-8'), grammar = fs.readFileSync('lib/parser/pbxproj.pegjs', 'utf-8'), - parser = PEG.buildParser(grammar), + parser = PEG.generate(grammar), rawProj = parser.parse(pbx), project = rawProj.project; diff --git a/test/parser/two-sections.js b/test/parser/two-sections.js index 863f5f6..bdc9484 100644 --- a/test/parser/two-sections.js +++ b/test/parser/two-sections.js @@ -2,7 +2,7 @@ var PEG = require('pegjs'), fs = require('fs'), pbx = fs.readFileSync('test/parser/projects/two-sections.pbxproj', 'utf-8'), grammar = fs.readFileSync('lib/parser/pbxproj.pegjs', 'utf-8'), - parser = PEG.buildParser(grammar), + parser = PEG.generate(grammar), rawProj = parser.parse(pbx), project = rawProj.project; diff --git a/test/parser/with_array.js b/test/parser/with_array.js index 0ff1e1d..c9c4f3d 100644 --- a/test/parser/with_array.js +++ b/test/parser/with_array.js @@ -2,7 +2,7 @@ var PEG = require('pegjs'), fs = require('fs'), pbx = fs.readFileSync('test/parser/projects/with_array.pbxproj', 'utf-8'), grammar = fs.readFileSync('lib/parser/pbxproj.pegjs', 'utf-8'), - parser = PEG.buildParser(grammar), + parser = PEG.generate(grammar), rawProj = parser.parse(pbx), project = rawProj.project; diff --git a/test/pbxFile.js b/test/pbxFile.js index 15797ea..a24f564 100644 --- a/test/pbxFile.js +++ b/test/pbxFile.js @@ -1,67 +1,81 @@ var pbxFile = require('../lib/pbxFile'); -exports['lastType'] = { +exports['lastKnownFileType'] = { 'should detect that a .m path means sourcecode.c.objc': function (test) { var sourceFile = new pbxFile('Plugins/ChildBrowser.m'); - test.equal('sourcecode.c.objc', sourceFile.lastType); + test.equal('sourcecode.c.objc', sourceFile.lastKnownFileType); test.done(); }, 'should detect that a .h path means sourceFile.c.h': function (test) { var sourceFile = new pbxFile('Plugins/ChildBrowser.h'); - test.equal('sourcecode.c.h', sourceFile.lastType); + test.equal('sourcecode.c.h', sourceFile.lastKnownFileType); test.done(); }, 'should detect that a .bundle path means "wrapper.plug-in"': function (test) { var sourceFile = new pbxFile('Plugins/ChildBrowser.bundle'); - test.equal('"wrapper.plug-in"', sourceFile.lastType); + test.equal('wrapper.plug-in', sourceFile.lastKnownFileType); test.done(); }, 'should detect that a .xib path means file.xib': function (test) { var sourceFile = new pbxFile('Plugins/ChildBrowser.xib'); - test.equal('file.xib', sourceFile.lastType); + test.equal('file.xib', sourceFile.lastKnownFileType); test.done(); }, 'should detect that a .dylib path means "compiled.mach-o.dylib"': function (test) { var sourceFile = new pbxFile('libsqlite3.dylib'); - test.equal('"compiled.mach-o.dylib"', sourceFile.lastType); + test.equal('compiled.mach-o.dylib', sourceFile.lastKnownFileType); + test.done(); + }, + + 'should detect that a .tbd path means sourcecode.text-based-dylib-definition': function (test) { + var sourceFile = new pbxFile('libsqlite3.tbd'); + + test.equal('sourcecode.text-based-dylib-definition', sourceFile.lastKnownFileType); test.done(); }, 'should detect that a .framework path means wrapper.framework': function (test) { var sourceFile = new pbxFile('MessageUI.framework'); - test.equal('wrapper.framework', sourceFile.lastType); + test.equal('wrapper.framework', sourceFile.lastKnownFileType); test.done(); }, 'should detect that a .a path means archive.ar': function (test) { var sourceFile = new pbxFile('libGoogleAnalytics.a'); - test.equal('archive.ar', sourceFile.lastType); + test.equal('archive.ar', sourceFile.lastKnownFileType); test.done(); }, - 'should allow lastType to be overridden': function (test) { + 'should detect that a .xcdatamodel path means wrapper.xcdatamodel': function (test) { + var sourceFile = new pbxFile('dataModel.xcdatamodel'); + + test.equal('wrapper.xcdatamodel', sourceFile.lastKnownFileType); + test.done(); + }, + + 'should allow lastKnownFileType to be overridden': function (test) { var sourceFile = new pbxFile('Plugins/ChildBrowser.m', - { lastType: 'somestupidtype' }); + { lastKnownFileType: 'somestupidtype' }); - test.equal('somestupidtype', sourceFile.lastType); + test.equal('somestupidtype', sourceFile.lastKnownFileType); test.done(); }, - 'should set lastType to unknown if undetectable': function (test) { + 'should set lastKnownFileType to unknown if undetectable': function (test) { var sourceFile = new pbxFile('Plugins/ChildBrowser.guh'); - test.equal('unknown', sourceFile.lastType); + test.equal('unknown', sourceFile.lastKnownFileType); test.done(); } } @@ -73,12 +87,30 @@ exports['group'] = { test.equal('Sources', sourceFile.group); test.done(); }, - 'should be Frameworks for frameworks': function (test) { + 'should be Sources for data model document files': function (test) { + var dataModelFile = new pbxFile('dataModel.xcdatamodeld'); + + test.equal('Sources', dataModelFile.group); + test.done(); + }, + 'should be Frameworks for dylibs': function (test) { var framework = new pbxFile('libsqlite3.dylib'); test.equal('Frameworks', framework.group); test.done(); }, + 'should be Frameworks for tbds': function (test) { + var framework = new pbxFile('libsqlite3.tbd'); + + test.equal('Frameworks', framework.group); + test.done(); + }, + 'should be Frameworks for frameworks': function (test) { + var framework = new pbxFile('MessageUI.framework'); + + test.equal('Frameworks', framework.group); + test.done(); + }, 'should be Resources for all other files': function (test) { var headerFile = new pbxFile('Plugins/ChildBrowser.h'), xibFile = new pbxFile('Plugins/ChildBrowser.xib'); @@ -112,6 +144,13 @@ exports['sourceTree'] = { test.done(); }, + 'should be SDKROOT for tbds': function (test) { + var sourceFile = new pbxFile('libsqlite3.tbd'); + + test.equal('SDKROOT', sourceFile.sourceTree); + test.done(); + }, + 'should be SDKROOT for frameworks': function (test) { var sourceFile = new pbxFile('MessageUI.framework'); @@ -150,6 +189,13 @@ exports['path'] = { test.done(); }, + 'should be "usr/lib" for tbds (relative to SDKROOT)': function (test) { + var sourceFile = new pbxFile('libsqlite3.tbd'); + + test.equal('usr/lib/libsqlite3.tbd', sourceFile.path); + test.done(); + }, + 'should be "System/Library/Frameworks" for frameworks': function (test) { var sourceFile = new pbxFile('MessageUI.framework'); @@ -173,7 +219,7 @@ exports['settings'] = { test.equal(undefined, sourceFile.settings); test.done(); }, - + 'should be undefined if weak is false or non-boolean': function (test) { var sourceFile1 = new pbxFile('social.framework', { weak: false }); @@ -191,5 +237,29 @@ exports['settings'] = { test.deepEqual({ATTRIBUTES:["Weak"]}, sourceFile.settings); test.done(); + }, + + 'should be {ATTRIBUTES:["CodeSignOnCopy"]} if sign specified': function (test) { + var sourceFile = new pbxFile('signable.framework', + { embed: true, sign: true }); + + test.deepEqual({ATTRIBUTES:["CodeSignOnCopy"]}, sourceFile.settings); + test.done(); + }, + + 'should be {ATTRIBUTES:["Weak","CodeSignOnCopy"]} if both weak linking and sign specified': function (test) { + var sourceFile = new pbxFile('signableWeak.framework', + { embed: true, weak: true, sign: true }); + + test.deepEqual({ATTRIBUTES:["Weak", "CodeSignOnCopy"]}, sourceFile.settings); + test.done(); + }, + + 'should be {COMPILER_FLAGS:"blah"} if compiler flags specified': function (test) { + var sourceFile = new pbxFile('Plugins/BarcodeScanner.m', + { compilerFlags: "-std=c++11 -fno-objc-arc" }); + + test.deepEqual({COMPILER_FLAGS:'"-std=c++11 -fno-objc-arc"'}, sourceFile.settings); + test.done(); } } diff --git a/test/pbxItemByComment.js b/test/pbxItemByComment.js new file mode 100644 index 0000000..d5d2146 --- /dev/null +++ b/test/pbxItemByComment.js @@ -0,0 +1,50 @@ +var fullProject = require('./fixtures/full-project') + fullProjectStr = JSON.stringify(fullProject), + pbx = require('../lib/pbxProject'), + proj = new pbx('.'); + +function cleanHash() { + return JSON.parse(fullProjectStr); +} + +exports.setUp = function (callback) { + proj.hash = cleanHash(); + callback(); +} + +exports.pbxItemByComment = { + 'should return PBXTargetDependency': function (test) { + var pbxItem = proj.pbxItemByComment('PBXTargetDependency', 'PBXTargetDependency'); + + test.ok(pbxItem); + test.equals(pbxItem.isa, 'PBXTargetDependency'); + test.done() + }, + 'should return PBXContainerItemProxy': function (test) { + var pbxItem = proj.pbxItemByComment('libPhoneGap.a', 'PBXReferenceProxy'); + + test.ok(pbxItem); + test.equals(pbxItem.isa, 'PBXReferenceProxy'); + test.done() + }, + 'should return PBXResourcesBuildPhase': function (test) { + var pbxItem = proj.pbxItemByComment('Resources', 'PBXResourcesBuildPhase'); + + test.ok(pbxItem); + test.equals(pbxItem.isa, 'PBXResourcesBuildPhase'); + test.done() + }, + 'should return PBXShellScriptBuildPhase': function (test) { + var pbxItem = proj.pbxItemByComment('Touch www folder', 'PBXShellScriptBuildPhase'); + + test.ok(pbxItem); + test.equals(pbxItem.isa, 'PBXShellScriptBuildPhase'); + test.done() + }, + 'should return null when PBXNativeTarget not found': function (test) { + var pbxItem = proj.pbxItemByComment('Invalid', 'PBXTargetDependency'); + + test.equal(pbxItem, null); + test.done() + } +} diff --git a/test/pbxProject.js b/test/pbxProject.js index df686db..eacb61b 100644 --- a/test/pbxProject.js +++ b/test/pbxProject.js @@ -155,6 +155,112 @@ exports['updateProductName function'] = { } } +exports['updateBuildProperty function'] = { + setUp:function(callback) { + callback(); + }, + tearDown:function(callback) { + fs.writeFileSync(bcpbx, original_pbx, 'utf-8'); + callback(); + }, + 'should change build properties in the .pbxproj file': function (test) { + var myProj = new pbx('test/parser/projects/build-config.pbxproj'); + myProj.parse(function(err, hash) { + myProj.updateBuildProperty('TARGETED_DEVICE_FAMILY', '"arm"'); + var newContents = myProj.writeSync(); + test.ok(newContents.match(/TARGETED_DEVICE_FAMILY\s*=\s*"arm"/)); + myProj.updateBuildProperty('OTHER_LDFLAGS', ['T','E','S','T']); + newContents = myProj.writeSync(); + test.ok(newContents.match(/OTHER_LDFLAGS\s*=\s*\(\s*T,\s*E,\s*S,\s*T,\s*\)/)) + test.done(); + }); + } +} + +exports['addBuildProperty function'] = { + setUp:function(callback) { + callback(); + }, + tearDown:function(callback) { + fs.writeFileSync(bcpbx, original_pbx, 'utf-8'); + callback(); + }, + 'should add 4 build properties in the .pbxproj file': function (test) { + var myProj = new pbx('test/parser/projects/build-config.pbxproj'); + myProj.parse(function(err, hash) { + myProj.addBuildProperty('ENABLE_BITCODE', 'NO'); + var newContents = myProj.writeSync(); + test.equal(newContents.match(/ENABLE_BITCODE\s*=\s*NO/g).length, 4); + test.done(); + }); + }, + 'should add 2 build properties in the .pbxproj file for specific build': function (test) { + var myProj = new pbx('test/parser/projects/build-config.pbxproj'); + myProj.parse(function(err, hash) { + myProj.addBuildProperty('ENABLE_BITCODE', 'NO', 'Release'); + var newContents = myProj.writeSync(); + test.equal(newContents.match(/ENABLE_BITCODE\s*=\s*NO/g).length, 2); + test.done(); + }); + }, + 'should not add build properties in the .pbxproj file for nonexist build': function (test) { + var myProj = new pbx('test/parser/projects/build-config.pbxproj'); + myProj.parse(function(err, hash) { + myProj.addBuildProperty('ENABLE_BITCODE', 'NO', 'nonexist'); + var newContents = myProj.writeSync(); + test.ok(!newContents.match(/ENABLE_BITCODE\s*=\s*NO/g)); + test.done(); + }); + } +} + +exports['removeBuildProperty function'] = { + setUp:function(callback) { + callback(); + }, + tearDown:function(callback) { + fs.writeFileSync(bcpbx, original_pbx, 'utf-8'); + callback(); + }, + 'should remove all build properties in the .pbxproj file': function (test) { + var myProj = new pbx('test/parser/projects/build-config.pbxproj'); + myProj.parse(function(err, hash) { + myProj.removeBuildProperty('IPHONEOS_DEPLOYMENT_TARGET'); + var newContents = myProj.writeSync(); + test.ok(!newContents.match(/IPHONEOS_DEPLOYMENT_TARGET/)); + test.done(); + }); + }, + 'should remove specific build properties in the .pbxproj file': function (test) { + var myProj = new pbx('test/parser/projects/build-config.pbxproj'); + myProj.parse(function(err, hash) { + myProj.removeBuildProperty('IPHONEOS_DEPLOYMENT_TARGET', 'Debug'); + var newContents = myProj.writeSync(); + test.equal(newContents.match(/IPHONEOS_DEPLOYMENT_TARGET/g).length, 2); + test.done(); + }); + }, + 'should not remove any build properties in the .pbxproj file': function (test) { + var myProj = new pbx('test/parser/projects/build-config.pbxproj'); + myProj.parse(function(err, hash) { + myProj.removeBuildProperty('IPHONEOS_DEPLOYMENT_TARGET', 'notexist'); + var newContents = myProj.writeSync(); + test.equal(newContents.match(/IPHONEOS_DEPLOYMENT_TARGET/g).length, 4); + test.done(); + }); + }, + 'should fine with remove inexist build properties in the .pbxproj file': function (test) { + var myProj = new pbx('test/parser/projects/build-config.pbxproj'); + myProj.parse(function(err, hash) { + myProj.removeBuildProperty('ENABLE_BITCODE'); + var newContents = myProj.writeSync(); + test.ok(!newContents.match(/ENABLE_BITCODE/)); + test.done(); + }); + } + +} + exports['productName field'] = { 'should return the product name': function (test) { var newProj = new pbx('.'); @@ -165,6 +271,28 @@ exports['productName field'] = { } } +exports['addPluginFile function'] = { + 'should strip the Plugin path prefix': function (test) { + var myProj = new pbx('test/parser/projects/full.pbxproj'); + + myProj.parse(function (err, hash) { + test.equal(myProj.addPluginFile('Plugins/testMac.m').path, 'testMac.m'); + test.equal(myProj.addPluginFile('Plugins\\testWin.m').path, 'testWin.m'); + test.done(); + }); + }, + 'should add files to the .pbxproj file using the / path seperator': function (test) { + var myProj = new pbx('test/parser/projects/full.pbxproj'); + + myProj.parse(function (err, hash) { + var file = myProj.addPluginFile('myPlugin\\newFile.m'); + + test.equal(myProj.pbxFileReferenceSection()[file.fileRef].path, '"myPlugin/newFile.m"'); + test.done(); + }); + } +} + exports['hasFile'] = { 'should return true if the file is in the project': function (test) { var newProj = new pbx('.'); diff --git a/test/pbxTargetByName.js b/test/pbxTargetByName.js new file mode 100644 index 0000000..a51cb74 --- /dev/null +++ b/test/pbxTargetByName.js @@ -0,0 +1,29 @@ +var fullProject = require('./fixtures/full-project') + fullProjectStr = JSON.stringify(fullProject), + pbx = require('../lib/pbxProject'), + proj = new pbx('.'); + +function cleanHash() { + return JSON.parse(fullProjectStr); +} + +exports.setUp = function (callback) { + proj.hash = cleanHash(); + callback(); +} + +exports.pbxTargetByName = { + 'should return PBXNativeTarget': function (test) { + var pbxTarget = proj.pbxTargetByName('KitchenSinktablet'); + + test.ok(pbxTarget); + test.equals(pbxTarget.isa, 'PBXNativeTarget'); + test.done() + }, + 'should return null when PBXNativeTarget not found': function (test) { + var pbxTarget = proj.pbxTargetByName('Invalid'); + + test.equal(pbxTarget, null); + test.done() + } +} diff --git a/test/pbxWriter.js b/test/pbxWriter.js index 982019f..d3b49e8 100644 --- a/test/pbxWriter.js +++ b/test/pbxWriter.js @@ -2,10 +2,15 @@ var pbx = require('../lib/pbxProject'), fs = require('fs'), myProj; -function testProjectContents(filename, test) { - var myProj = new pbx(filename), - content = fs.readFileSync(filename, 'utf-8'); +function testProjectContents(filename, test, expectedFilename) { + var myProj = new pbx(filename); + var content; + if (expectedFilename) { + content = fs.readFileSync(expectedFilename, 'utf-8'); + } else { + content = fs.readFileSync(filename, 'utf-8'); + } // normalize tabs vs strings content = content.replace(/ /g, '\t'); @@ -46,7 +51,10 @@ exports.writeSync = { testProjectContents('test/parser/projects/hash.pbxproj', test); }, 'should write out the "with_array" test': function (test) { - testProjectContents('test/parser/projects/with_array.pbxproj', test); + // Special case in that the originating project does not have a trailing comma for all of its array entries. + // This is definitely possibly. + // But when we write/read it out again during testing, the trailing commas are introduced by our library. + testProjectContents('test/parser/projects/with_array.pbxproj', test, 'test/parser/projects/expected/with_array_expected.pbxproj'); }, 'should write out the "section" test': function (test) { testProjectContents('test/parser/projects/section.pbxproj', test); diff --git a/test/removeFramework.js b/test/removeFramework.js index 869752d..ffca3b4 100644 --- a/test/removeFramework.js +++ b/test/removeFramework.js @@ -1,4 +1,4 @@ -var fullProject = require('./fixtures/full-project') +var fullProject = require('./fixtures/full-project'), fullProjectStr = JSON.stringify(fullProject), pbx = require('../lib/pbxProject'), pbxFile = require('../lib/pbxFile'), @@ -13,27 +13,56 @@ exports.setUp = function (callback) { callback(); } +function nonComments(obj) { + var keys = Object.keys(obj), + newObj = {}, i = 0; + + for (i; i < keys.length; i++) { + if (!/_comment$/.test(keys[i])) { + newObj[keys[i]] = obj[keys[i]]; + } + } + + return newObj; +} + +function frameworkSearchPaths(proj) { + var configs = nonComments(proj.pbxXCBuildConfigurationSection()), + allPaths = [], + ids = Object.keys(configs), i, buildSettings; + + for (i = 0; i< ids.length; i++) { + buildSettings = configs[ids[i]].buildSettings; + + if (buildSettings['FRAMEWORK_SEARCH_PATHS']) { + allPaths.push(buildSettings['FRAMEWORK_SEARCH_PATHS']); + } + } + + return allPaths; +} + exports.removeFramework = { 'should return a pbxFile': function (test) { var newFile = proj.addFramework('libsqlite3.dylib'); test.equal(newFile.constructor, pbxFile); - + var deletedFile = proj.removeFramework('libsqlite3.dylib'); test.equal(deletedFile.constructor, pbxFile); - + test.done() }, 'should set a fileRef on the pbxFile': function (test) { var newFile = proj.addFramework('libsqlite3.dylib'); test.ok(newFile.fileRef); - + var deletedFile = proj.removeFramework('libsqlite3.dylib'); test.ok(deletedFile.fileRef); - + test.done() }, 'should remove 2 fields from the PBXFileReference section': function (test) { @@ -51,7 +80,7 @@ exports.removeFramework = { test.equal(66, frsLength); test.ok(!fileRefSection[deletedFile.fileRef]); test.ok(!fileRefSection[deletedFile.fileRef + '_comment']); - + test.done(); }, 'should remove 2 fields from the PBXBuildFile section': function (test) { @@ -64,13 +93,13 @@ exports.removeFramework = { test.ok(buildFileSection[newFile.uuid + '_comment']); var deletedFile = proj.removeFramework('libsqlite3.dylib'); - + bfsLength = Object.keys(buildFileSection).length; test.equal(58, bfsLength); test.ok(!buildFileSection[deletedFile.uuid]); test.ok(!buildFileSection[deletedFile.uuid + '_comment']); - + test.done(); }, 'should remove from the Frameworks PBXGroup': function (test) { @@ -79,12 +108,12 @@ exports.removeFramework = { frameworks = proj.pbxGroupByName('Frameworks'); test.equal(frameworks.children.length, newLength); - + var deletedFile = proj.removeFramework('libsqlite3.dylib'), newLength = newLength - 1; test.equal(frameworks.children.length, newLength); - + test.done(); }, 'should remove from the PBXFrameworksBuildPhase': function (test) { @@ -92,12 +121,33 @@ exports.removeFramework = { frameworks = proj.pbxFrameworksBuildPhaseObj(); test.equal(frameworks.files.length, 16); - + var deletedFile = proj.removeFramework('libsqlite3.dylib'), frameworks = proj.pbxFrameworksBuildPhaseObj(); test.equal(frameworks.files.length, 15); - + + test.done(); + }, + 'should remove custom frameworks': function (test) { + var newFile = proj.addFramework('/path/to/Custom.framework', { customFramework: true }), + frameworks = proj.pbxFrameworksBuildPhaseObj(); + + test.equal(frameworks.files.length, 16); + + var deletedFile = proj.removeFramework('/path/to/Custom.framework', { customFramework: true }), + frameworks = proj.pbxFrameworksBuildPhaseObj(); + + test.equal(frameworks.files.length, 15); + + var frameworkPaths = frameworkSearchPaths(proj); + expectedPath = '"/path/to"'; + + for (i = 0; i < frameworkPaths.length; i++) { + var current = frameworkPaths[i]; + test.ok(current.indexOf(expectedPath) == -1); + } + test.done(); } } diff --git a/test/removeResourceFile.js b/test/removeResourceFile.js index 7260aa5..25b1347 100644 --- a/test/removeResourceFile.js +++ b/test/removeResourceFile.js @@ -140,7 +140,7 @@ exports.removeResourceFile = { test.equal(fileRefEntry.isa, 'PBXFileReference'); test.equal(fileRefEntry.fileEncoding, undefined); - test.equal(fileRefEntry.lastKnownFileType, '"wrapper.plug-in"'); + test.equal(fileRefEntry.lastKnownFileType, 'wrapper.plug-in'); test.equal(fileRefEntry.name, '"assets.bundle"'); test.equal(fileRefEntry.path, '"Resources/assets.bundle"'); test.equal(fileRefEntry.sourceTree, '""'); diff --git a/test/removeSourceFile.js b/test/removeSourceFile.js index 63c4dfd..e31e727 100644 --- a/test/removeSourceFile.js +++ b/test/removeSourceFile.js @@ -126,6 +126,21 @@ exports.removeSourceFile = { test.ok(!sourceObj); test.done(); + }, + 'should remove file from PBXFileReference after modified by Xcode': function(test) { + var fileRef = proj.addSourceFile('Plugins/file.m').fileRef; + + // Simulate Xcode's behaviour of stripping quotes around path and name + // properties. + var entry = proj.pbxFileReferenceSection()[fileRef]; + entry.name = entry.name.replace(/^"(.*)"$/, "$1"); + entry.path = entry.path.replace(/^"(.*)"$/, "$1"); + + var newFile = proj.removeSourceFile('Plugins/file.m'); + + test.ok(newFile.uuid); + test.ok(!proj.pbxFileReferenceSection()[fileRef]); + test.done(); } } diff --git a/test/variantGroup.js b/test/variantGroup.js new file mode 100644 index 0000000..4b3733e --- /dev/null +++ b/test/variantGroup.js @@ -0,0 +1,177 @@ +var pbx = require('../lib/pbxProject'), + project, + projectHash; + +var findChildInGroup = function(obj, target) { + var found = false; + + for (var i = 0, j = obj.children.length; i < j; i++) { + if (obj.children[i].value === target) { + found = true; + break; + } + } + + return found; +} + +var findFileByUUID = function(obj, target) { + var found = false; + + for (var k = 0, l = obj.files.length; k < l; k++) { + if (obj.files[k].value === target) { + found = true; + break; + } + } + + return found; +} + +var findByFileRef = function(obj, target) { + var found = false; + + for (var property in obj) { + if (!/comment/.test(property)) { + if (obj[property].fileRef === target) { + found = true; + break; + } + } + } + return found; +} + +var findByName = function(obj, target) { + var found = false; + for (var property in obj) { + if (!/comment/.test(property)) { + var value = obj[property]; + if (value.name === target) { + found = true; + } + } + } + return found; +} + +exports.setUp = function(callback) { + project = new pbx('test/parser/projects/variantgroup.pbxproj'); + projectHash = project.parseSync(); + callback(); +} + +exports.getVariantGroupByKey = { + 'should return PBXVariantGroup for Localizable.strings': function(test) { + var groupKey = project.findPBXVariantGroupKey({name: 'Localizable.strings'}); + var group = project.getPBXVariantGroupByKey(groupKey); + test.ok(group.name === 'Localizable.strings'); + test.done(); + } +} + +exports.createVariantGroup = { + 'should create a new Test Variant Group': function(test) { + delete project.getPBXObject('PBXVariantGroup'); + + var found = false; + var groups = project.getPBXObject('PBXVariantGroup'); + + var found = findByName(groups, 'Test'); + test.ok(found === false); + + var group = project.findPBXVariantGroupKey({name:'Test'}); + test.ok(group === undefined); + + project.pbxCreateVariantGroup('Test'); + + groups = project.getPBXObject('PBXVariantGroup'); + found = findByName(groups, 'Test'); + test.ok(found === true); + + group = project.findPBXVariantGroupKey({name:'Test'}); + test.ok(typeof group === 'string'); + test.done(); + } +} + +exports.findVariantGroupKey = { + 'should return a valid group key':function(test) { + var keyByName = project.findPBXVariantGroupKey({ name: 'Localizable.strings'}); + var nonExistingKey = project.findPBXVariantGroupKey({ name: 'Foo'}); + + test.ok(keyByName === '07E3BDBC1DF1DEA500E49912'); + test.ok(nonExistingKey === undefined); + + test.done(); + } +} + +exports.createLocalisationVariantGroup = { + 'should create a new localisation variationgroup then add group to Resources group': function(test) { + delete project.getPBXObject('PBXVariantGroup'); + + var localizationVariantGp = project.addLocalizationVariantGroup('InfoPlist.strings'); + + var resourceGroupKey = project.findPBXGroupKey({name: 'Resources'}); + var resourceGroup = project.getPBXGroupByKey(resourceGroupKey); + var foundInResourcesGroup = findChildInGroup(resourceGroup, localizationVariantGp.fileRef ); + test.ok(foundInResourcesGroup); + + var foundInResourcesBuildPhase = false; + var sources = project.pbxResourcesBuildPhaseObj(); + for (var i = 0, j = sources.files.length; i < j; i++) { + var file = sources.files[i]; + if (file.value === localizationVariantGp.uuid) { + foundInResourcesBuildPhase = true; + } + } + test.ok(foundInResourcesBuildPhase); + + test.done(); + } +} + +exports.addResourceFileToLocalisationGroup = { + 'should add resource file to the TestVariantGroup group' : function(test) { + + var infoPlistVarGp = project.addLocalizationVariantGroup('InfoPlist.strings'); + var testKey = infoPlistVarGp.fileRef; + var file = project.addResourceFile('Resources/en.lproj/Localization.strings', {variantGroup: true}, testKey); + + var foundInLocalisationVariantGroup = findChildInGroup(project.getPBXVariantGroupByKey(testKey), file.fileRef ); + test.ok(foundInLocalisationVariantGroup); + + var foundInResourcesBuildPhase = false; + var sources = project.pbxResourcesBuildPhaseObj(); + for (var i = 0, j = sources.files.length; i < j; i++) { + var sourceFile = sources.files[i]; + if (sourceFile.value === file.fileRef) { + foundInResourcesBuildPhase = true; + } + } + test.ok(!foundInResourcesBuildPhase); + + var buildFileSection = project.pbxBuildFileSection(); + test.ok(buildFileSection[file.uuid] === undefined); + + test.done(); + } +} + +exports.removeResourceFileFromGroup = { + 'should add resource file then remove resource file from Localizable.strings group' : function(test) { + var testKey = project.findPBXVariantGroupKey({name:'Localizable.strings'}); + var file = project.addResourceFile('Resources/zh.lproj/Localization.strings', {}, testKey); + + var foundInGroup = findChildInGroup(project.getPBXVariantGroupByKey(testKey),file.fileRef ); + test.ok(foundInGroup); + + project.removeResourceFile('Resources/zh.lproj/Localization.strings', {}, testKey); + + var foundInGroup = findChildInGroup(project.getPBXVariantGroupByKey(testKey),file.fileRef ); + test.ok(!foundInGroup); + + test.done(); + } +} \ No newline at end of file diff --git a/test/xcode5searchPaths.js b/test/xcode5searchPaths.js new file mode 100644 index 0000000..d76489a --- /dev/null +++ b/test/xcode5searchPaths.js @@ -0,0 +1,58 @@ +var xcode5proj = require('./fixtures/library-search-paths') + xcode5projStr = JSON.stringify(xcode5proj), + pbx = require('../lib/pbxProject'), + pbxFile = require('../lib/pbxFile'), + proj = new pbx('.'), + libPoop = { path: 'some/path/poop.a' }; + +function cleanHash() { + return JSON.parse(xcode5projStr); +} + +exports.setUp = function (callback) { + proj.hash = cleanHash(); + callback(); +} + +var PRODUCT_NAME = '"$(TARGET_NAME)"'; + +exports.addAndRemoveToFromLibrarySearchPaths = { + 'add should add the path to each configuration section':function(test) { + var expected = '"\\"$(SRCROOT)/$(TARGET_NAME)/some/path\\""', + config = proj.pbxXCBuildConfigurationSection(), + ref, lib, refSettings; + + proj.addToLibrarySearchPaths(libPoop); + + for (ref in config) { + if (ref.indexOf('_comment') > -1) + continue; + + refSettings = config[ref].buildSettings; + + if (refSettings.PRODUCT_NAME != PRODUCT_NAME) + continue; + + lib = refSettings.LIBRARY_SEARCH_PATHS; + test.equal(lib[1], expected); + } + test.done(); + }, + + 'remove should remove from the path to each configuration section':function(test) { + var config, ref, lib; + + proj.addToLibrarySearchPaths(libPoop); + proj.removeFromLibrarySearchPaths(libPoop); + + config = proj.pbxXCBuildConfigurationSection(); + for (ref in config) { + if (ref.indexOf('_comment') > -1 || config[ref].buildSettings.PRODUCT_NAME != PRODUCT_NAME) continue; + + lib = config[ref].buildSettings.LIBRARY_SEARCH_PATHS; + test.ok(lib.length === 1); + test.ok(lib[0].indexOf('$(SRCROOT)/KitchenSinktablet/some/path') == -1); + } + test.done(); + } +}