1 | var path = require('path'),
|
2 | util = require('util');
|
3 |
|
4 | var DEFAULT_SOURCETREE = '"<group>"',
|
5 | DEFAULT_PRODUCT_SOURCETREE = 'BUILT_PRODUCTS_DIR',
|
6 | DEFAULT_FILEENCODING = 4,
|
7 | DEFAULT_GROUP = 'Resources',
|
8 | DEFAULT_FILETYPE = 'unknown';
|
9 |
|
10 | var FILETYPE_BY_EXTENSION = {
|
11 | a: 'archive.ar',
|
12 | app: 'wrapper.application',
|
13 | appex: 'wrapper.app-extension',
|
14 | bundle: 'wrapper.plug-in',
|
15 | dylib: 'compiled.mach-o.dylib',
|
16 | framework: 'wrapper.framework',
|
17 | h: 'sourcecode.c.h',
|
18 | m: 'sourcecode.c.objc',
|
19 | markdown: 'text',
|
20 | mdimporter: 'wrapper.cfbundle',
|
21 | octest: 'wrapper.cfbundle',
|
22 | pch: 'sourcecode.c.h',
|
23 | plist: 'text.plist.xml',
|
24 | sh: 'text.script.sh',
|
25 | swift: 'sourcecode.swift',
|
26 | tbd: 'sourcecode.text-based-dylib-definition',
|
27 | xcassets: 'folder.assetcatalog',
|
28 | xcconfig: 'text.xcconfig',
|
29 | xcdatamodel: 'wrapper.xcdatamodel',
|
30 | xcodeproj: 'wrapper.pb-project',
|
31 | xctest: 'wrapper.cfbundle',
|
32 | xib: 'file.xib',
|
33 | strings: 'text.plist.strings'
|
34 | },
|
35 | GROUP_BY_FILETYPE = {
|
36 | 'archive.ar': 'Frameworks',
|
37 | 'compiled.mach-o.dylib': 'Frameworks',
|
38 | 'sourcecode.text-based-dylib-definition': 'Frameworks',
|
39 | 'wrapper.framework': 'Frameworks',
|
40 | 'embedded.framework': 'Embed Frameworks',
|
41 | 'sourcecode.c.h': 'Resources',
|
42 | 'sourcecode.c.objc': 'Sources',
|
43 | 'sourcecode.swift': 'Sources'
|
44 | },
|
45 | PATH_BY_FILETYPE = {
|
46 | 'compiled.mach-o.dylib': 'usr/lib/',
|
47 | 'sourcecode.text-based-dylib-definition': 'usr/lib/',
|
48 | 'wrapper.framework': 'System/Library/Frameworks/'
|
49 | },
|
50 | SOURCETREE_BY_FILETYPE = {
|
51 | 'compiled.mach-o.dylib': 'SDKROOT',
|
52 | 'sourcecode.text-based-dylib-definition': 'SDKROOT',
|
53 | 'wrapper.framework': 'SDKROOT'
|
54 | },
|
55 | ENCODING_BY_FILETYPE = {
|
56 | 'sourcecode.c.h': 4,
|
57 | 'sourcecode.c.h': 4,
|
58 | 'sourcecode.c.objc': 4,
|
59 | 'sourcecode.swift': 4,
|
60 | 'text': 4,
|
61 | 'text.plist.xml': 4,
|
62 | 'text.script.sh': 4,
|
63 | 'text.xcconfig': 4,
|
64 | 'text.plist.strings': 4
|
65 | };
|
66 |
|
67 |
|
68 | function unquoted(text){
|
69 | return text.replace (/(^")|("$)/g, '')
|
70 | }
|
71 |
|
72 | function detectType(filePath) {
|
73 | var extension = path.extname(filePath).substring(1),
|
74 | filetype = FILETYPE_BY_EXTENSION[unquoted(extension)];
|
75 |
|
76 | if (!filetype) {
|
77 | return DEFAULT_FILETYPE;
|
78 | }
|
79 |
|
80 | return filetype;
|
81 | }
|
82 |
|
83 | function defaultExtension(fileRef) {
|
84 | var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType;
|
85 |
|
86 | for(var extension in FILETYPE_BY_EXTENSION) {
|
87 | if(FILETYPE_BY_EXTENSION.hasOwnProperty(unquoted(extension)) ) {
|
88 | if(FILETYPE_BY_EXTENSION[unquoted(extension)] === filetype )
|
89 | return extension;
|
90 | }
|
91 | }
|
92 | }
|
93 |
|
94 | function defaultEncoding(fileRef) {
|
95 | var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType,
|
96 | encoding = ENCODING_BY_FILETYPE[unquoted(filetype)];
|
97 |
|
98 | if (encoding) {
|
99 | return encoding;
|
100 | }
|
101 | }
|
102 |
|
103 | function detectGroup(fileRef, opt) {
|
104 | var extension = path.extname(fileRef.basename).substring(1),
|
105 | filetype = fileRef.lastKnownFileType || fileRef.explicitFileType,
|
106 | groupName = GROUP_BY_FILETYPE[unquoted(filetype)];
|
107 |
|
108 | if (extension === 'xcdatamodeld') {
|
109 | return 'Sources';
|
110 | }
|
111 |
|
112 | if (opt.customFramework && opt.embed) {
|
113 | return GROUP_BY_FILETYPE['embedded.framework'];
|
114 | }
|
115 |
|
116 | if (!groupName) {
|
117 | return DEFAULT_GROUP;
|
118 | }
|
119 |
|
120 | return groupName;
|
121 | }
|
122 |
|
123 | function detectSourcetree(fileRef) {
|
124 |
|
125 | var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType,
|
126 | sourcetree = SOURCETREE_BY_FILETYPE[unquoted(filetype)];
|
127 |
|
128 | if (fileRef.explicitFileType) {
|
129 | return DEFAULT_PRODUCT_SOURCETREE;
|
130 | }
|
131 |
|
132 | if (fileRef.customFramework) {
|
133 | return DEFAULT_SOURCETREE;
|
134 | }
|
135 |
|
136 | if (!sourcetree) {
|
137 | return DEFAULT_SOURCETREE;
|
138 | }
|
139 |
|
140 | return sourcetree;
|
141 | }
|
142 |
|
143 | function defaultPath(fileRef, filePath) {
|
144 | var filetype = fileRef.lastKnownFileType || fileRef.explicitFileType,
|
145 | defaultPath = PATH_BY_FILETYPE[unquoted(filetype)];
|
146 |
|
147 | if (fileRef.customFramework) {
|
148 | return filePath;
|
149 | }
|
150 |
|
151 | if (defaultPath) {
|
152 | return path.join(defaultPath, path.basename(filePath));
|
153 | }
|
154 |
|
155 | return filePath;
|
156 | }
|
157 |
|
158 | function defaultGroup(fileRef) {
|
159 | var groupName = GROUP_BY_FILETYPE[fileRef.lastKnownFileType];
|
160 |
|
161 | if (!groupName) {
|
162 | return DEFAULT_GROUP;
|
163 | }
|
164 |
|
165 | return defaultGroup;
|
166 | }
|
167 |
|
168 | function pbxFile(filepath, opt) {
|
169 | var opt = opt || {};
|
170 |
|
171 | this.basename = path.basename(filepath);
|
172 | this.lastKnownFileType = opt.lastKnownFileType || detectType(filepath);
|
173 | this.group = detectGroup(this, opt);
|
174 |
|
175 |
|
176 | if (opt.customFramework == true) {
|
177 | this.customFramework = true;
|
178 | this.dirname = path.dirname(filepath).replace(/\\/g, '/');
|
179 | }
|
180 |
|
181 | this.path = defaultPath(this, filepath).replace(/\\/g, '/');
|
182 | this.fileEncoding = this.defaultEncoding = opt.defaultEncoding || defaultEncoding(this);
|
183 |
|
184 |
|
185 | if (opt.explicitFileType) {
|
186 | this.explicitFileType = opt.explicitFileType;
|
187 | this.basename = this.basename + '.' + defaultExtension(this);
|
188 | delete this.path;
|
189 | delete this.lastKnownFileType;
|
190 | delete this.group;
|
191 | delete this.defaultEncoding;
|
192 | }
|
193 |
|
194 | this.sourceTree = opt.sourceTree || detectSourcetree(this);
|
195 | this.includeInIndex = 0;
|
196 |
|
197 | if (opt.weak && opt.weak === true)
|
198 | this.settings = { ATTRIBUTES: ['Weak'] };
|
199 |
|
200 | if (opt.compilerFlags) {
|
201 | if (!this.settings)
|
202 | this.settings = {};
|
203 | this.settings.COMPILER_FLAGS = util.format('"%s"', opt.compilerFlags);
|
204 | }
|
205 |
|
206 | if (opt.embed && opt.sign) {
|
207 | if (!this.settings)
|
208 | this.settings = {};
|
209 | if (!this.settings.ATTRIBUTES)
|
210 | this.settings.ATTRIBUTES = [];
|
211 | this.settings.ATTRIBUTES.push('CodeSignOnCopy');
|
212 | }
|
213 | }
|
214 |
|
215 | module.exports = pbxFile;
|