Package: xUnique
xUnique, is a pure Python script to regenerateproject.pbxproj,
a.k.a the Xcode project file, and make it unique and same on any
machine.As you may know, the UUID generated by Xcode (a.k.arfc4122) in the file is not
unique for the same added file( or other entries like groups,build
phases,etc.) on different machines, which makes it a developer’s
nightmare to merge and resolve conflicts inproject.pbxproj.xUniqueconvert all the 96bitsUUID(24 alphanumeric chars) to
MD5 hex digest(32 hex chars), and Xcode do recognize these MD5 digests.What it does & How it worksconvertproject.pbxprojto JSON formatIterate allobjectsin JSON and give every UUID an absolute path,
and create a new UUID using MD5 hex digest of the pathAll elements in this json object is actually connected as a treeWe give a path attribute to every node of the tree using its
unique attribute; this path is the absolute path to the root node,Apply MD5 hex digest to the path for the nodeReplace all old UUIDs with the MD5 hex digest and also remove unused
UUIDs that are not in the current node tree and UUIDs in wrong formatSort the project file inlcudingchildren,files,PBXFileReferenceandPBXBuildFilelist and remove all
duplicated entries in these listsseesort_pbxprojmethod in xUnique.py if you want to know the
implementation;It’s ported from my modifiedsort-Xcode-project-file,
with some differences in orderingPBXFileReferenceandPBXBuildFileWith differentoptions, you can usexUniquewith more flexibilityChange LogThechange logcontains the list of changes and latest version information of each
version. Please downloadLatest Releasefor production environment
usage.Installationinstall fromPyPi:$pipinstallxUniqueinstall locally:$pythonsetup.pyinstallIt will install a command line scriptxuniquein dir/usr/local/bin(make sure you have added this dir to your$PATH). So you can invoke xUnique directly from command line:$xunique-hHow to useThere are many ways to use this script after you installedxUnique. I will introduce two:Xcode “build post-action” (Recommended)openEdit Schemein Xcode (shortcut:⌘+Shift+,)choose the scheme you use to run your projectexpandBuild, selectPost-actionsclick symbol+on the left bottom corner of the right panechooseNew Run Script Actionchoose your selected scheme name inProvide build settings frominput commands below:$xunique"${PROJECT_FILE_PATH}/project.pbxproj"clickCloseand it’s all done.Next time when you Build or Run the project, xUnique would be
triggered after build success. If the build works, you could commit
all files.Demo gif animation ishereGit hookcreate a git hook in Terminal like:${echo'#!/bin/sh';echo'xunique path/to/MyProject.xcodeproj';}>.git/hooks/pre-commitAdd permissionchmod 755.git/hooks/pre-commitxUnique will be triggered when you trying to commit:Using option-cin command would fail the commit operation if
project file is modified. Then you can add the modified project
file and commit all the files again.Option-cis not activated by default. The commit operation
will proceed successfully even if the project file is modified by
xUnique. So do not push the commit unless you add the modified
project file again and do another commit.CocoaPods usersIf your project uses CocoaPods AND addedPodsdirectory to source control, you may also need to uniquifyPods.xcodeproj:Xcode “build post-action” : add extra command below$xunique"${PODS_ROOT}/Pods.xcodeproj"Git hook: add one more command in hook script${echo'#!/bin/sh';echo'xunique path/to/MyProject.xcodeproj';echo'xunique path/to/Pods.xcodeproj';}>.git/hooks/pre-commitSupported argument optionsUse options in xUnique:$xunique[options]"path_to/YourProject.xcodeproj/or_project.pbxproj"-vprint verbose output, and generatedebug_result.jsonfile for debug.-uuniquify project file, that is, replace UUID to MD5 digest.-ssort project file includingchildren,files,PBXFileReferenceandPBXBuildFilelist and remove all duplicated entries in these lists. Supports both original and uniquified project file.-psortPBXFileReferenceandPBXBuildFilesections in project file ordered by file names. Only works with-s. Before v4.0.0, this was hard-coded in-soption and cannot be turned off. Starting from v4.0.0, without this option along with-s, xUnique will sort these two types by MD5 digests, the same as Xcode does.-cWhen project file was modified, xUnique quit with non-zero status. Without this option, the status code would be zero if so. This option is usually used in Git hook to submit xUnique result combined with your original new commit.Note: If neither-unor-sexists,-u-swill be appended to existing option list.ExamplesAPNS Pusheris a Xcode project which contains a subproject named “Fragaria” as git submodule. UsexUniqueto convert it. You can clonemy forked repoand try to open and build it in Xcode. You will find thatxUniquedoes not affect the project at all.The initial diff result could be foundhere.The diff result with my modifiedsort-Xcode-project-filewithPBXBuildFileandPBXFileReferencesort support could be foundhere.Pure python sort result could be foundherePBX sections sorted by MD5 digest result (default in v4.0.0) could be
foundbelowadd xUnique to Xcode post actionNOTICEAll project members must add the build post-action or git hook. Thus
the project file would be consistent in the repository.Tested supportedisatypes:PBXProjectXCConfigurationListPBXNativeTargetPBXTargetDependencyPBXContainerItemProxyXCBuildConfigurationPBXSourcesBuildPhasePBXFrameworksBuildPhasePBXResourcesBuildPhasePBXFrameworksBuildPhasePBXCopyFilesBuildPhasePBXHeadersBuildPhasePBXShellScriptBuildPhasePBXBuildRulePBXBuildFilePBXReferenceProxyPBXFileReferencePBXGroupPBXVariantGroupAuthorsXiao Wang (seganw)ContributionsI only tested on several single projects and several projects with a
subproject, so maybe there should be more unconsidered conditions. If
you get any problem, feel free to fire a Pull Request or IssueYou can also buy me a cup of tea:LicenseLicensed under the Apache License, Version 2.0 (the “License”); you may
not use this file except in compliance with the License. You may obtain
a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an “AS IS” BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.