@@ -487,14 +487,16 @@ pbxProject.prototype.removeFromPbxBuildFileSection = function(file) {
487487 for ( uuid in this . pbxBuildFileSection ( ) ) {
488488 if ( this . pbxBuildFileSection ( ) [ uuid ] . fileRef_comment == file . basename ) {
489489 file . uuid = uuid ;
490- delete this . pbxBuildFileSection ( ) [ uuid ] ;
491-
492- var commentKey = f ( "%s_comment" , uuid ) ;
493- delete this . pbxBuildFileSection ( ) [ commentKey ] ;
490+ this . removeFromPbxBuildFileSectionByUuid ( uuid ) ;
494491 }
495492 }
496493}
497494
495+ pbxProject . prototype . removeFromPbxBuildFileSectionByUuid = function ( uuid ) {
496+ var buildSection = this . pbxBuildFileSection ( ) ;
497+ removeItemAndCommentFromSectionByUuid ( buildSection , uuid ) ;
498+ }
499+
498500pbxProject . prototype . findMainPbxGroup = function ( ) {
499501 var groups = this . hash . project . objects [ 'PBXGroup' ] ;
500502 var candidates = [ ] ;
@@ -604,7 +606,6 @@ pbxProject.prototype.addPbxGroup = function (filePathsArray, name, path, sourceT
604606 this . addToPbxBuildFileSection ( file ) ;
605607 pbxGroup . children . push ( pbxGroupChild ( file ) ) ;
606608 }
607-
608609 }
609610
610611 if ( groups ) {
@@ -1599,9 +1600,181 @@ pbxProject.prototype.addTarget = function(name, type, subfolder) {
15991600
16001601 // Return target on success
16011602 return target ;
1603+ } ;
1604+
1605+ pbxProject . prototype . removeTargetsByProductType = function ( targetProductType ) {
1606+ var nativeTargetsNonComments = nonComments ( this . pbxNativeTargetSection ( ) ) ;
1607+
1608+ for ( var nativeTargetUuid in nativeTargetsNonComments ) {
1609+ var target = nativeTargetsNonComments [ nativeTargetUuid ] ;
1610+ if ( target . productType === targetProductType || target . productType === `"${ targetProductType } "` ) {
1611+ this . removeTarget ( target , nativeTargetUuid ) ;
1612+ }
1613+ }
1614+ }
1615+
1616+ pbxProject . prototype . removeTarget = function ( target , targetKey ) {
1617+ let files = [ ] ;
1618+
1619+ // iterate all buildPhases and collect all files that should be removed
1620+ // remove the phase from the appropriate section
1621+ var buildPhases = target [ "buildPhases" ] ;
1622+ for ( let i = 0 ; i < buildPhases . length ; i ++ ) {
1623+ var buildPhase = buildPhases [ i ] ;
1624+ var sectionUuid = buildPhase . value ;
1625+ var section = { } ; //in case we don't recognise the section
1626+ if ( buildPhase . comment === buildPhaseNameForIsa ( "PBXSourcesBuildPhase" ) ) {
1627+ var section = this . hash . project . objects [ "PBXSourcesBuildPhase" ] ;
1628+ files = files . concat ( section [ sectionUuid ] . files ) ;
1629+ } else if ( buildPhase . comment === buildPhaseNameForIsa ( "PBXResourcesBuildPhase" ) ) {
1630+ var section = this . hash . project . objects [ "PBXResourcesBuildPhase" ] ;
1631+ files = files . concat ( section [ sectionUuid ] . files ) ;
1632+ } else if ( buildPhase . comment === buildPhaseNameForIsa ( "PBXFrameworksBuildPhase" ) ) {
1633+ var section = this . hash . project . objects [ "PBXFrameworksBuildPhase" ] ;
1634+ files = files . concat ( section [ sectionUuid ] . files ) ;
1635+ }
1636+
1637+ removeItemAndCommentFromSectionByUuid ( section , sectionUuid ) ;
1638+ }
1639+
1640+ //remove files from all build phases from PBXBuildFile section
1641+ for ( let k = 0 ; k < files . length ; k ++ ) {
1642+ const uuid = files [ k ] . value ;
1643+ this . removeFromPbxBuildFileSectionByUuid ( uuid ) ;
1644+ }
1645+
1646+ //remove target from the project itself
1647+ var targets = this . pbxProjectSection ( ) [ this . getFirstProject ( ) [ 'uuid' ] ] [ 'targets' ]
1648+ for ( let l = 0 ; l < targets . length ; l ++ ) {
1649+ if ( targets [ l ] . value === targetKey ) {
1650+ targets . splice ( l , 1 ) ;
1651+ }
1652+ }
1653+
1654+ //remove target build configurations
1655+ //get configurationList object and get all configuration uuids
1656+ var buildConfigurationList = target [ "buildConfigurationList" ] ;
1657+ var pbxXCConfigurationListSection = this . pbxXCConfigurationList ( ) ;
1658+ var xcConfigurationList = pbxXCConfigurationListSection [ buildConfigurationList ] || { } ;
1659+ var buildConfigurations = xcConfigurationList . buildConfigurations || [ ] ;
16021660
1661+ //remove all configurations from XCBuildConfiguration section
1662+ var pbxBuildConfigurationSection = this . pbxXCBuildConfigurationSection ( )
1663+ for ( let m = 0 ; m < buildConfigurations . length ; m ++ ) {
1664+ const configuration = buildConfigurations [ m ] ;
1665+ removeItemAndCommentFromSectionByUuid ( pbxBuildConfigurationSection , configuration . value ) ;
1666+ }
1667+
1668+ //remove the XCConfigurationList from the section
1669+ removeItemAndCommentFromSectionByUuid ( pbxXCConfigurationListSection , buildConfigurationList ) ;
1670+
1671+ //get target product information
1672+ var productUuid = "" ;
1673+
1674+ var productReferenceUuid = target . productReference ;
1675+ var pbxBuildFileSection = this . pbxBuildFileSection ( ) ;
1676+ var pbxBuildFileSectionNoComments = nonComments ( pbxBuildFileSection ) ;
1677+
1678+ // the productReference is the uuid from the PBXFileReference Section, but we need the one in PBXBuildFile section
1679+ // check the fileRef of all records until we find the product
1680+ for ( uuid in pbxBuildFileSectionNoComments ) {
1681+ if ( this . pbxBuildFileSection ( ) [ uuid ] . fileRef == productReferenceUuid ) {
1682+ productUuid = uuid ;
1683+ }
1684+ }
1685+
1686+ //remove copy phase
1687+ var pbxCopySection = this . hash . project . objects [ "PBXCopyFilesBuildPhase" ] ;
1688+ var noCommentsCopySection = nonComments ( pbxCopySection ) ;
1689+ for ( var copyPhaseId in noCommentsCopySection ) {
1690+ var copyPhase = noCommentsCopySection [ copyPhaseId ] ;
1691+ if ( copyPhase . files ) {
1692+
1693+ //check if the product of the target is part of this copy phase files
1694+ for ( let p = 0 ; p < copyPhase . files . length ; p ++ ) {
1695+ const copyFile = copyPhase . files [ p ] ;
1696+ if ( copyFile . value === productUuid ) {
1697+ //if this is the only file in the copy phase - delete the whole phase and remove it from all targets
1698+ if ( copyPhase . files . length === 1 ) {
1699+ var nativeTargetsnoComments = nonComments ( this . pbxNativeTargetSection ( ) ) ;
1700+ for ( var nativeTargetUuid in nativeTargetsnoComments ) {
1701+ const nativeTarget = nativeTargetsnoComments [ nativeTargetUuid ] ;
1702+ for ( var phaseIndex in nativeTarget . buildPhases ) {
1703+ if ( nativeTarget . buildPhases [ phaseIndex ] . value == copyPhaseId ) {
1704+ //remove copy build phase from containing target
1705+ nativeTarget . buildPhases . splice ( phaseIndex , 1 ) ;
1706+ break ;
1707+ }
1708+ }
1709+ }
1710+
1711+ //remove from copySection
1712+ removeItemAndCommentFromSectionByUuid ( pbxCopySection , copyPhaseId ) ;
1713+ } else {
1714+ //if there are other files in the copy phase, just remove the product
1715+ copyPhase . files ( p , 1 ) ;
1716+ }
1717+ break ;
1718+ }
1719+ }
1720+ }
1721+ }
1722+
1723+ //remove the product from the PBXBuildFile section
1724+ removeItemAndCommentFromSectionByUuid ( pbxBuildFileSection , productUuid ) ;
1725+
1726+
1727+ //remove the product from the Products PBXGroup
1728+ var fileReferenceSection = this . pbxFileReferenceSection ( ) ;
1729+ var productReference = fileReferenceSection [ productReferenceUuid ] ;
1730+ var productFile = new pbxFile ( productReference . path ) ;
1731+ productFile . fileRef = productReferenceUuid ;
1732+ productFile . uuid = productReferenceUuid ;
1733+ this . removeFromProductsPbxGroup ( productFile ) ;
1734+
1735+ //remove the product from the PBXFileReference section
1736+ removeItemAndCommentFromSectionByUuid ( fileReferenceSection , productReferenceUuid ) ;
1737+
1738+
1739+ //find all PBXTargetDependency that refer the target and remove them with the PBXContainerItemProxy
1740+ var pbxTargetDependency = 'PBXTargetDependency' ;
1741+ var pbxContainerItemProxy = 'PBXContainerItemProxy' ;
1742+ var pbxTargetDependencySection = this . hash . project . objects [ pbxTargetDependency ] ;
1743+ var pbxTargetDependencySectionNoComments = nonComments ( pbxTargetDependencySection ) ;
1744+ var pbxContainerItemProxySection = this . hash . project . objects [ pbxContainerItemProxy ] ;
1745+
1746+ for ( var targetDependencyUuid in pbxTargetDependencySectionNoComments ) {
1747+ targetDependency = pbxTargetDependencySectionNoComments [ targetDependencyUuid ] ;
1748+ if ( targetDependency . target === targetKey ) {
1749+ //remove the PBXContainerItemProxy
1750+ removeItemAndCommentFromSectionByUuid ( pbxContainerItemProxySection , targetDependency . targetProxy ) ;
1751+ //remove the PBXTargetDependency from dependencies from all targets
1752+ for ( var nativeTargetUuid in nativeTargetsnoComments ) {
1753+ const nativeTarget = nativeTargetsnoComments [ nativeTargetUuid ] ;
1754+ for ( var dependencyIndex in nativeTarget . dependencies ) {
1755+ if ( nativeTarget . dependencies [ dependencyIndex ] . value == targetDependencyUuid ) {
1756+ nativeTarget . dependencies . splice ( dependencyIndex , 1 ) ;
1757+ }
1758+ }
1759+ }
1760+ //remove the PBXTargetDependency
1761+ removeItemAndCommentFromSectionByUuid ( pbxTargetDependencySection , targetDependencyUuid ) ;
1762+ }
1763+ }
1764+
1765+ //remove the target from PBXNativeTarget section
1766+ var nativeTargets = this . pbxNativeTargetSection ( ) ;
1767+ removeItemAndCommentFromSectionByUuid ( nativeTargets , nativeTargetUuid ) ;
1768+
1769+ this . removePbxGroup ( unquote ( target . name ) ) ;
16031770} ;
16041771
1772+ function removeItemAndCommentFromSectionByUuid ( section , uuid ) {
1773+ var commentKey = f ( "%s_comment" , uuid )
1774+ delete section [ commentKey ] ;
1775+ delete section [ uuid ] ;
1776+ }
1777+
16051778// helper recursive prop search+replace
16061779function propReplace ( obj , prop , value ) {
16071780 var o = { } ;
0 commit comments