xUnique, is a pure Python script to regenerate project.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.a
rfc4122 <http://www.ietf.org/rfc/rfc4122.txt>
__) 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 in project.pbxproj
.
xUnique convert all the 96bits UUID
\ (24 alphanumeric chars) to
MD5 hex digest(32 hex chars), and Xcode do recognize these MD5 digests.
project.pbxproj
to JSON formatobjects
in JSON and give every UUID an absolute path,and create a new UUID using MD5 hex digest of the path
UUIDs that are not in the current node tree and UUIDs in wrong format
children
, files
,PBXFileReference
and PBXBuildFile
list and remove all
duplicated entries in these lists
sort_pbxproj
method in xUnique.py if you want to know the
implementation;sort-Xcode-project-file <https://github.com/truebit/webkit/commits/master/Tools/Scripts/sort-Xcode-project-file>
__,
with some differences in ordering PBXFileReference
and
PBXBuildFile
options <https://github.com/truebit/xUnique#supported-argument-options>
__, you can usexUnique with more flexibility
The change log <https://github.com/truebit/xUnique/releases>
__
contains the list of changes and latest version information of each
version. Please download Latest Release
for production environment
usage.
install from PyPi <https://pypi.python.org/pypi/xUnique>
__:
.. code-block:: bash
$ pip install xUnique
install locally:
.. code-block:: bash
$ python setup.py install
It will install a command line script xunique
in dir /usr/local/bin
(make sure you have added this dir to your $PATH
). So you can invoke xUnique directly from command line:
.. code-block:: bash
$ xunique -h
There are many ways to use this script after you installed xUnique . I will introduce two.
My recommended method is git hook rather than other methods in Xcode, such like build post action or shell script build phase. The reason is that Xcode may trigger these actions unnoticed when you've changed some files. That may cause a failure.
You could still use Xcode actions if you do not got such problems. But if you do got strange failures, try git hook method.
Git hook (Recommended)
#. create a git hook in Terminal like:
.. code-block:: bash
$ { echo '#!/bin/sh'; echo 'xunique path/to/MyProject.xcodeproj'; } > .git/hooks/pre-commit
#. Add permission ``chmod 755 .git/hooks/pre-commit``
#. xUnique will be triggered when you trying to commit:
- Using option ``-c`` in 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 ``-c`` is 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.
Xcode "build post-action"
Edit Scheme
in Xcode (shortcut:``⌘``\ +\ ``Shift``\ +\ ``,``)
Build
, select Post-actions
+
on the left bottom corner of the right paneNew Run Script Action
Provide build settings from
.. code-block:: bash
$ xunique "${PROJECT_FILE_PATH}/project.pbxproj"
Close
and it's all done.triggered after build success. If the build works, you could commit
all files.
here <https://github.com/truebit/xUnique#add-xunique-to-xcode-post-action>
__CocoaPods users
If your project uses CocoaPods AND added ``Pods`` directory to source control, you may also need to uniquify ``Pods.xcodeproj``:
- Xcode "build post-action" : add extra command below
.. code-block:: bash
$ xunique "${PODS_ROOT}/Pods.xcodeproj"
**Note** : according to `Cocoapods wiki <https://github.com/CocoaPods/CocoaPods/wiki/Generate-ASCII-format-xcodeproj>`__,
make sure `xcproj <https://github.com/0xced/xcproj>`__ is installed in ``$PATH``.
- Git hook: add one more command in hook script
.. code-block:: bash
$ { echo '#!/bin/sh'; echo 'xunique path/to/MyProject.xcodeproj'; echo 'xunique path/to/Pods.xcodeproj'; } > .git/hooks/pre-commit
**Note**: If ``project.pbxproj`` file is in XML format, please install `xcproj <https://github.com/0xced/xcproj>`__ and add it to your $PATH. This would make Cocoapods converting it to Xcode default format automatically:
.. code-block:: bash
brew install xcproj
`Detailed Cocoapods explanation here <https://github.com/CocoaPods/CocoaPods/wiki/Generate-ASCII-format-xcodeproj>`__
Supported argument options
Use options in xUnique:
.. code-block:: bash
$ xunique [options] "path_to/YourProject.xcodeproj/or_project.pbxproj"
-v print verbose output, and generate debug_result.json
file for debug.
-u uniquify project file, that is, replace UUID to MD5 digest.
-s sort project file including children
, files
, PBXFileReference
and PBXBuildFile
list and remove all duplicated entries in these lists. Supports both original and uniquified project file.
-p sort PBXFileReference
and PBXBuildFile
sections in project file ordered by file names. Only works with -s
. Before v4.0.0, this was hard-coded in -s
option 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.
-c When 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 -u
nor -s
exists, -u -s
will be appended to existing option list.
APNS Pusher <https://github.com/blommegard/APNS-Pusher>
is a Xcode project which contains a subproject named "Fragaria" as git submodule. Use xUnique to convert it. You can clone my forked repo <https://github.com/truebit/APNS-Pusher>
and try to open and build it in Xcode. You will find that xUnique
does not affect the project at all.here <https://github.com/truebit/APNS-Pusher/commit/fb27af54627ca0836aa5eb847766441b991220bf>
__.sort-Xcode-project-file <https://github.com/truebit/webkit/blob/7afa105d20fccdec68d8bd778b649409f17cbdc0/Tools/Scripts/sort-Xcode-project-file>
with PBXBuildFile
and PBXFileReference
sort support could be found here <https://github.com/truebit/APNS-Pusher/commit/d5ff3dc053c4be96d6c209cc9ced890faad263c9>
.here <https://github.com/truebit/APNS-Pusher/commit/f79d182b0b5892cbb889b67242845807689bd5e4>
__below <https://github.com/truebit/APNS-Pusher/commit/5171c08d601500f6d9bda24cbd640074e1e2b3d7>
__add xUnique to Xcode post action
.. figure:: https://raw.github.com/truebit/xUnique/gif/xUnique_Build_Post_Action.gif
:alt: xUnique\_Build\_Post\_Action
NOTICE
------
- All project members must add the build post-action or git hook. Thus
the project file would be consistent in the repository.
- Tested supported ``isa`` types:
- ``PBXProject``
- ``XCConfigurationList``
- ``PBXNativeTarget``
- ``PBXTargetDependency``
- ``PBXContainerItemProxy``
- ``XCBuildConfiguration``
- ``PBXSourcesBuildPhase``
- ``PBXFrameworksBuildPhase``
- ``PBXResourcesBuildPhase``
- ``PBXFrameworksBuildPhase``
- ``PBXCopyFilesBuildPhase``
- ``PBXHeadersBuildPhase``
- ``PBXShellScriptBuildPhase``
- ``PBXBuildRule``
- ``PBXBuildFile``
- ``PBXReferenceProxy``
- ``PBXFileReference``
- ``PBXGroup``
- ``PBXVariantGroup``
Authors
-------
- Xiao Wang (`seganw <http://fclef.wordpress.com/about>`__)
Contributions
-------------
- I 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 Issue
- You can also buy me a cup of tea: |Donate to xUnique|
License
-------
Licensed 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 at
::
http://www.apache.org/licenses/LICENSE-2.0
Unless 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.
.. |Donate to xUnique| image:: https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif
:target: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=QQNATFYESVT76&item_name=xUnique