1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | var path = require('path'),
|
19 | util = require('util');
|
20 |
|
21 | var DEFAULT_SOURCETREE = '"<group>"',
|
22 | DEFAULT_PRODUCT_SOURCETREE = 'BUILT_PRODUCTS_DIR',
|
23 | DEFAULT_FILEENCODING = 4,
|
24 | DEFAULT_GROUP = 'Resources',
|
25 | DEFAULT_FILETYPE = 'unknown';
|
26 |
|
27 | var 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 |
|
85 | function unquoted(text){
|
86 | return text == null ? '' : text.replace (/(^")|("$)/g, '')
|
87 | }
|
88 |
|
89 | function 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 |
|
100 | function 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 |
|
112 | function 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 |
|
121 | function 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 |
|
141 | function 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 |
|
161 | function 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 |
|
176 | function 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 |
|
186 | function 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 |
|
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 |
|
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 |
|
233 | module.exports = pbxFile;
|