1
1
var util = require ( 'util' ) ,
2
2
f = util . format ,
3
3
EventEmitter = require ( 'events' ) . EventEmitter ,
4
- path = require ( 'path' ) ,
4
+ $ path = require ( 'path' ) ,
5
5
uuid = require ( 'node-uuid' ) ,
6
6
fork = require ( 'child_process' ) . fork ,
7
7
pbxWriter = require ( './pbxWriter' ) ,
8
- pbxFile = require ( './pbxFile' ) ,
8
+ pbxFile = require ( './pbxFile' ) . pbxFile ,
9
+ pbxFileTypes = require ( './pbxFile' ) . fileTypes ,
9
10
fs = require ( 'fs' ) ,
10
11
parser = require ( './parser/pbxproj' ) ,
11
12
COMMENT_KEY = / _ c o m m e n t $ / ,
12
- NO_SPECIAL_SYMBOLS = / ^ [ a - z A - Z 0 - 9 _ \. \$ ] + \. [ a - z A - Z ] + $ / ;
13
+ NO_SPECIAL_SYMBOLS = / ^ [ a - z A - Z 0 - 9 _ \. \$ ] + \. [ a - z A - Z ] + $ / ,
14
+ HEADER_FILE_TYPE_SUFFIX = ".h" ,
15
+ SOURCE_CODE_FILE_TYPE_PREFIX = "sourcecode." ;
13
16
14
17
function pbxProject ( filename ) {
15
18
if ( ! ( this instanceof pbxProject ) )
16
19
return new pbxProject ( filename ) ;
17
20
18
- this . filepath = path . resolve ( filename )
21
+ this . filepath = $ path. resolve ( filename )
19
22
}
20
23
21
24
util . inherits ( pbxProject , EventEmitter )
@@ -286,31 +289,52 @@ pbxProject.prototype.removeFromPbxBuildFileSection = function (file) {
286
289
}
287
290
}
288
291
289
- pbxProject . prototype . addPbxGroup = function ( filePathsArray , name , path , sourceTree ) {
292
+ pbxProject . prototype . findMainPbxGroup = function ( ) {
293
+ var groups = this . hash . project . objects [ 'PBXGroup' ] ;
294
+ var candidates = [ ] ;
295
+ for ( var key in groups ) {
296
+ if ( ! groups [ key ] . path && ! groups [ key ] . name && groups [ key ] . isa ) {
297
+ candidates . push ( groups [ key ] ) ;
298
+ }
299
+ }
300
+ if ( candidates . length == 1 ) {
301
+ return candidates [ 0 ] ;
302
+ }
303
+
304
+ return null ;
305
+ }
306
+
307
+ pbxProject . prototype . addPbxGroup = function ( filePathsArray , name , path , sourceTree , opt ) {
308
+
309
+ var oldGroup = this . pbxGroupByName ( name ) ;
310
+ if ( oldGroup ) {
311
+ this . removePbxGroup ( name , path ) ;
312
+ }
313
+
290
314
var groups = this . hash . project . objects [ 'PBXGroup' ] ,
291
- pbxGroupUuid = this . generateUuid ( ) ,
315
+ pbxGroupUuid = opt . uuid || this . generateUuid ( ) ,
292
316
commentKey = f ( "%s_comment" , pbxGroupUuid ) ,
293
317
pbxGroup = {
294
318
isa : 'PBXGroup' ,
295
319
children : [ ] ,
296
320
name : name ,
297
- path : path ,
298
321
sourceTree : sourceTree ? sourceTree : '"<group>"'
299
- } ,
322
+ } , //path is mandatory only for the main group
300
323
fileReferenceSection = this . pbxFileReferenceSection ( ) ,
301
324
filePathToReference = { } ;
302
-
325
+
303
326
for ( var key in fileReferenceSection ) {
304
327
// only look for comments
305
328
if ( ! COMMENT_KEY . test ( key ) ) continue ;
306
-
329
+
307
330
var fileReferenceKey = key . split ( COMMENT_KEY ) [ 0 ] ,
308
331
fileReference = fileReferenceSection [ fileReferenceKey ] ;
309
-
332
+
310
333
filePathToReference [ fileReference . path ] = { fileRef : fileReferenceKey , basename : fileReferenceSection [ key ] } ;
311
334
}
312
335
313
336
for ( var index = 0 ; index < filePathsArray . length ; index ++ ) {
337
+
314
338
var filePath = filePathsArray [ index ] ,
315
339
filePathQuoted = "\"" + filePath + "\"" ;
316
340
if ( filePathToReference [ filePath ] ) {
@@ -320,23 +344,80 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT
320
344
pbxGroup . children . push ( pbxGroupChild ( filePathToReference [ filePathQuoted ] ) ) ;
321
345
continue ;
322
346
}
323
-
324
- var file = new pbxFile ( filePath ) ;
325
- file . uuid = this . generateUuid ( ) ;
326
- file . fileRef = this . generateUuid ( ) ;
327
- this . addToPbxFileReferenceSection ( file ) ; // PBXFileReference
328
- this . addToPbxBuildFileSection ( file ) ; // PBXBuildFile
329
- pbxGroup . children . push ( pbxGroupChild ( file ) ) ;
347
+
348
+ var srcRootPath = $path . dirname ( $path . dirname ( this . filepath ) ) ;
349
+ var file = new pbxFile ( $path . relative ( srcRootPath , filePath ) ) ;
350
+ if ( fs . lstatSync ( filePath ) . isDirectory ( ) ) {
351
+ file . uuid = this . generateUuid ( ) ;
352
+ file . fileRef = file . uuid ;
353
+ this . addToPbxFileReferenceSection ( file ) ; // PBXFileReference
354
+ this . addToPbxBuildFileSection ( file ) ;
355
+ pbxGroup . children . push ( pbxGroupChild ( file ) ) ;
356
+ var files = fs . readdirSync ( filePath ) . map ( p => $path . join ( filePath , p ) ) ;
357
+ this . addPbxGroup ( files , $path . basename ( filePath ) , filePath , null , { uuid : file . uuid } ) ;
358
+ } else if ( file . lastType . startsWith ( SOURCE_CODE_FILE_TYPE_PREFIX ) ) {
359
+ file . uuid = this . generateUuid ( ) ;
360
+ file . fileRef = this . generateUuid ( ) ;
361
+ this . addToPbxFileReferenceSection ( file ) ; // PBXFileReference
362
+ this . addToPbxBuildFileSection ( file ) ; // PBXBuildFile
363
+ if ( ! file . lastType . endsWith ( HEADER_FILE_TYPE_SUFFIX ) ) {
364
+ this . addToPbxSourcesBuildPhase ( file ) ;
365
+ }
366
+ pbxGroup . children . push ( pbxGroupChild ( file ) ) ;
367
+ }
368
+
330
369
}
331
-
370
+
332
371
if ( groups ) {
333
372
groups [ pbxGroupUuid ] = pbxGroup ;
334
373
groups [ commentKey ] = name ;
335
374
}
336
-
375
+
376
+ if ( opt . isMain ) {
377
+ let mainGroup = this . findMainPbxGroup ( ) ;
378
+ if ( mainGroup ) {
379
+ var file = new pbxFile ( $path . relative ( this . filepath , path ) ) ;
380
+ file . fileRef = pbxGroupUuid ;
381
+ mainGroup . children . push ( pbxGroupChild ( file ) ) ;
382
+ }
383
+ }
384
+
337
385
return { uuid : pbxGroupUuid , pbxGroup : pbxGroup } ;
338
386
}
339
387
388
+ pbxProject . prototype . removePbxGroup = function ( name , path ) {
389
+ var group = this . pbxGroupByName ( name ) ;
390
+ if ( ! group ) {
391
+ return ;
392
+ }
393
+
394
+ var children = group . children ;
395
+
396
+ for ( i in children ) {
397
+ var file = new pbxFile ( $path . join ( path , children [ i ] . comment ) ) ;
398
+ file . fileRef = children [ i ] . value ;
399
+ file . uuid = file . fileRef ;
400
+ this . removePbxGroup ( children [ i ] . comment , $path . join ( path , children [ i ] . comment ) ) ;
401
+ this . removeFromPbxFileReferenceSection ( file ) ;
402
+ this . removeFromPbxBuildFileSection ( file ) ;
403
+ this . removeFromPbxSourcesBuildPhase ( file ) ;
404
+ }
405
+
406
+ //copied from https://github.com/alunny/node-xcode/blob/master/lib/pbxProject.js#L527
407
+ var section = this . hash . project . objects [ 'PBXGroup' ] ,
408
+ key , itemKey ;
409
+
410
+ for ( key in section ) {
411
+ // only look for comments
412
+ if ( ! COMMENT_KEY . test ( key ) ) continue ;
413
+
414
+ if ( section [ key ] == name ) {
415
+ itemKey = key . split ( COMMENT_KEY ) [ 0 ] ;
416
+ delete section [ itemKey ] ;
417
+ }
418
+ }
419
+ }
420
+
340
421
pbxProject . prototype . addToPbxFileReferenceSection = function ( file ) {
341
422
var commentKey = f ( "%s_comment" , file . fileRef ) ;
342
423
@@ -852,7 +933,7 @@ pbxProject.prototype.removeFromHeaderSearchPaths = function (file) {
852
933
INHERITED = '"$(inherited)"' ,
853
934
SEARCH_PATHS = 'HEADER_SEARCH_PATHS' ,
854
935
config , buildSettings , searchPaths ;
855
- var new_path = searchPathForFile ( file , this ) ;
936
+ var new_path = typeof file === 'string' ? file : searchPathForFile ( file , this ) ;
856
937
857
938
for ( config in configurations ) {
858
939
buildSettings = configurations [ config ] . buildSettings ;
@@ -1048,7 +1129,7 @@ function searchPathForFile(file, proj) {
1048
1129
1049
1130
var plugins = proj . pbxGroupByName ( 'Plugins' ) ,
1050
1131
pluginsPath = plugins ? plugins . path : null ,
1051
- fileDir = path . dirname ( file . path ) ;
1132
+ fileDir = $ path. dirname ( file . path ) ;
1052
1133
1053
1134
if ( fileDir == '.' ) {
1054
1135
fileDir = '' ;
0 commit comments