UNPKG

6.96 kBJavaScriptView Raw
1/**
2 Licensed to the Apache Software Foundation (ASF) under one
3 or more contributor license agreements. See the NOTICE file
4 distributed with this work for additional information
5 regarding copyright ownership. The ASF licenses this file
6 to you under the Apache License, Version 2.0 (the
7 'License'); you may not use this file except in compliance
8 with the License. You may obtain a copy of the License at
9 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing,
11 software distributed under the License is distributed on an
12 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 KIND, either express or implied. See the License for the
14 specific language governing permissions and limitations
15 under the License.
16 */
17
18var path = require('path'),
19 util = require('util');
20
21var DEFAULT_SOURCETREE = '"<group>"',
22 DEFAULT_PRODUCT_SOURCETREE = 'BUILT_PRODUCTS_DIR',
23 DEFAULT_FILEENCODING = 4,
24 DEFAULT_GROUP = 'Resources',
25 DEFAULT_FILETYPE = 'unknown';
26
27var FILETYPE_BY_EXTENSION = {
28 a: 'archive.ar',
29 app: 'wrapper.application',
30 appex: 'wrapper.app-extension',
31 bundle: 'wrapper.plug-in',
32 dylib: 'compiled.mach-o.dylib',
33 framework: 'wrapper.framework',
34 h: 'sourcecode.c.h',
35 m: 'sourcecode.c.objc',
36 markdown: 'text',
37 mdimporter: 'wrapper.cfbundle',
38 octest: 'wrapper.cfbundle',
39 pch: 'sourcecode.c.h',
40 plist: 'text.plist.xml',
41 sh: 'text.script.sh',
42 swift: 'sourcecode.swift',
43 tbd: 'sourcecode.text-based-dylib-definition',
44 xcassets: 'folder.assetcatalog',
45 xcconfig: 'text.xcconfig',
46 xcdatamodel: 'wrapper.xcdatamodel',
47 xcodeproj: 'wrapper.pb-project',
48 xctest: 'wrapper.cfbundle',
49 xib: 'file.xib',
50 strings: 'text.plist.strings'
51 },
52 GROUP_BY_FILETYPE = {
53 'archive.ar': 'Frameworks',
54 'compiled.mach-o.dylib': 'Frameworks',
55 'sourcecode.text-based-dylib-definition': 'Frameworks',
56 'wrapper.framework': 'Frameworks',
57 'embedded.framework': 'Embed Frameworks',
58 'sourcecode.c.h': 'Resources',
59 'sourcecode.c.objc': 'Sources',
60 'sourcecode.swift': 'Sources'
61 },
62 PATH_BY_FILETYPE = {
63 'compiled.mach-o.dylib': 'usr/lib/',
64 'sourcecode.text-based-dylib-definition': 'usr/lib/',
65 'wrapper.framework': 'System/Library/Frameworks/'
66 },
67 SOURCETREE_BY_FILETYPE = {
68 'compiled.mach-o.dylib': 'SDKROOT',
69 'sourcecode.text-based-dylib-definition': 'SDKROOT',
70 'wrapper.framework': 'SDKROOT'
71 },
72 ENCODING_BY_FILETYPE = {
73 'sourcecode.c.h': 4,
74 'sourcecode.c.h': 4,
75 'sourcecode.c.objc': 4,
76 'sourcecode.swift': 4,
77 'text': 4,
78 'text.plist.xml': 4,
79 'text.script.sh': 4,
80 'text.xcconfig': 4,
81 'text.plist.strings': 4
82 };
83
84
85function unquoted(text){
86 return text == null ? '' : text.replace (/(^")|("$)/g, '')
87}
88
89function detectType(filePath) {
90 var extension = path.extname(filePath).substring(1),
91 filetype = FILETYPE_BY_EXTENSION[unquoted(extension)];
92
93 if (!filetype) {
94 return DEFAULT_FILETYPE;
95 }
96
97 return filetype;
98}
99
100function defaultExtension(fileRef) {
101 var filetype = fileRef.lastKnownFileType && fileRef.lastKnownFileType != DEFAULT_FILETYPE ?
102 fileRef.lastKnownFileType : fileRef.explicitFileType;
103
104 for(var extension in FILETYPE_BY_EXTENSION) {
105 if(FILETYPE_BY_EXTENSION.hasOwnProperty(unquoted(extension)) ) {
106 if(FILETYPE_BY_EXTENSION[unquoted(extension)] === unquoted(filetype) )
107 return extension;
108 }
109 }
110}
111
112function defaultEncoding(fileRef) {
113 var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType,
114 encoding = ENCODING_BY_FILETYPE[unquoted(filetype)];
115
116 if (encoding) {
117 return encoding;
118 }
119}
120
121function detectGroup(fileRef, opt) {
122 var extension = path.extname(fileRef.basename).substring(1),
123 filetype = fileRef.lastKnownFileType || fileRef.explicitFileType,
124 groupName = GROUP_BY_FILETYPE[unquoted(filetype)];
125
126 if (extension === 'xcdatamodeld') {
127 return 'Sources';
128 }
129
130 if (opt.customFramework && opt.embed) {
131 return GROUP_BY_FILETYPE['embedded.framework'];
132 }
133
134 if (!groupName) {
135 return DEFAULT_GROUP;
136 }
137
138 return groupName;
139}
140
141function detectSourcetree(fileRef) {
142
143 var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType,
144 sourcetree = SOURCETREE_BY_FILETYPE[unquoted(filetype)];
145
146 if (fileRef.explicitFileType) {
147 return DEFAULT_PRODUCT_SOURCETREE;
148 }
149
150 if (fileRef.customFramework) {
151 return DEFAULT_SOURCETREE;
152 }
153
154 if (!sourcetree) {
155 return DEFAULT_SOURCETREE;
156 }
157
158 return sourcetree;
159}
160
161function defaultPath(fileRef, filePath) {
162 var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType,
163 defaultPath = PATH_BY_FILETYPE[unquoted(filetype)];
164
165 if (fileRef.customFramework) {
166 return filePath;
167 }
168
169 if (defaultPath) {
170 return path.join(defaultPath, path.basename(filePath));
171 }
172
173 return filePath;
174}
175
176function defaultGroup(fileRef) {
177 var groupName = GROUP_BY_FILETYPE[fileRef.lastKnownFileType];
178
179 if (!groupName) {
180 return DEFAULT_GROUP;
181 }
182
183 return defaultGroup;
184}
185
186function pbxFile(filepath, opt) {
187 var opt = opt || {};
188
189 this.basename = path.basename(filepath);
190 this.lastKnownFileType = opt.lastKnownFileType || detectType(filepath);
191 this.group = detectGroup(this, opt);
192
193 // for custom frameworks
194 if (opt.customFramework == true) {
195 this.customFramework = true;
196 this.dirname = path.dirname(filepath).replace(/\\/g, '/');
197 }
198
199 this.path = defaultPath(this, filepath).replace(/\\/g, '/');
200 this.fileEncoding = this.defaultEncoding = opt.defaultEncoding || defaultEncoding(this);
201
202 // When referencing products / build output files
203 if (opt.explicitFileType) {
204 this.explicitFileType = opt.explicitFileType;
205 this.basename = this.basename + '.' + defaultExtension(this);
206 delete this.path;
207 delete this.lastKnownFileType;
208 delete this.group;
209 delete this.defaultEncoding;
210 }
211
212 this.sourceTree = opt.sourceTree || detectSourcetree(this);
213 this.includeInIndex = 0;
214
215 if (opt.weak && opt.weak === true)
216 this.settings = { ATTRIBUTES: ['Weak'] };
217
218 if (opt.compilerFlags) {
219 if (!this.settings)
220 this.settings = {};
221 this.settings.COMPILER_FLAGS = util.format('"%s"', opt.compilerFlags);
222 }
223
224 if (opt.embed && opt.sign) {
225 if (!this.settings)
226 this.settings = {};
227 if (!this.settings.ATTRIBUTES)
228 this.settings.ATTRIBUTES = [];
229 this.settings.ATTRIBUTES.push('CodeSignOnCopy');
230 }
231}
232
233module.exports = pbxFile;