{ "info": { "author": "Xiao Wang", "author_email": "wangxiao8611@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Programming Language :: Objective C", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Topic :: Software Development :: Build Tools", "Topic :: Software Development :: Version Control" ], "description": "xUnique\n=======\n\n*xUnique*, is a pure Python script to regenerate ``project.pbxproj``,\na.k.a the Xcode project file, and make it unique and same on any\nmachine.\n\nAs you may know, the UUID generated by Xcode (a.k.a\n`rfc4122 `__) in the file is not\nunique for the same added file( or other entries like groups,build\nphases,etc.) on different machines, which makes it a developer's\nnightmare to merge and resolve conflicts in ``project.pbxproj``.\n\n*xUnique* convert all the 96bits ``UUID``\\ (24 alphanumeric chars) to\nMD5 hex digest(32 hex chars), and Xcode do recognize these MD5 digests.\n\nWhat it does & How it works\n---------------------------\n\n#. convert ``project.pbxproj`` to JSON format\n#. Iterate all ``objects`` in JSON and give every UUID an absolute path,\n and create a new UUID using MD5 hex digest of the path\n\n - All elements in this json object is actually connected as a tree\n - We give a path attribute to every node of the tree using its\n unique attribute; this path is the absolute path to the root node,\n - Apply MD5 hex digest to the path for the node\n\n#. Replace all old UUIDs with the MD5 hex digest and also remove unused\n UUIDs that are not in the current node tree and UUIDs in wrong format\n#. Sort the project file inlcuding ``children``, ``files``,\n ``PBXFileReference`` and ``PBXBuildFile`` list and remove all\n duplicated entries in these lists\n\n - see ``sort_pbxproj`` method in xUnique.py if you want to know the\n implementation;\n - It's ported from my modified `sort-Xcode-project-file `__,\n with some differences in ordering ``PBXFileReference`` and\n ``PBXBuildFile``\n\n#. With different `options `__, you can use\n *xUnique* with more flexibility\n\nChange Log\n----------\n\nThe `change log `__\ncontains the list of changes and latest version information of each\nversion. Please download ``Latest Release`` for production environment\nusage.\n\n\nInstallation\n------------\n- install from `PyPi `__:\n \n .. code-block:: bash\n\n $ pip install xUnique\n\n- install locally:\n\n .. code-block:: bash\n\n $ python setup.py install\n\nIt 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:\n\n.. code-block:: bash\n\n $ xunique -h\n\n\nHow to use\n----------\n\nThere are many ways to use this script after you installed *xUnique* . I will introduce two:\n\nXcode \"build post-action\" (Recommended)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n#. open ``Edit Scheme`` in Xcode (shortcut:\n ``\u2318``\\ +\\ ``Shift``\\ +\\ ``,``)\n#. choose the scheme you use to run your project\n#. expand ``Build``, select ``Post-actions``\n#. click symbol ``+`` on the left bottom corner of the right pane\n#. choose ``New Run Script Action``\n#. choose your selected scheme name in ``Provide build settings from``\n#. input commands below:\n \n .. code-block:: bash\n\n $ xunique \"${PROJECT_FILE_PATH}/project.pbxproj\"\n\n#. click ``Close`` and it's all done.\n#. Next time when you Build or Run the project, xUnique would be\n triggered after build success. If the build works, you could commit\n all files.\n#. Demo gif animation is `here `__\n\nGit hook\n~~~~~~~~\n\n#. create a git hook in Terminal like: \n \n .. code-block:: bash\n\n $ { echo '#!/bin/sh'; echo 'xunique path/to/MyProject.xcodeproj'; } > .git/hooks/pre-commit\n\n#. Add permission ``chmod 755 .git/hooks/pre-commit``\n#. xUnique will be triggered when you trying to commit:\n\n - Using option ``-c`` in command would fail the commit operation if\n project file is modified. Then you can add the modified project\n file and commit all the files again.\n - Option ``-c`` is not activated by default. The commit operation\n will proceed successfully even if the project file is modified by\n xUnique. So do not push the commit unless you add the modified\n project file again and do another commit.\n\nCocoaPods users\n~~~~~~~~~~~~~~~\n\nIf your project uses CocoaPods AND added ``Pods`` directory to source control, you may also need to uniquify ``Pods.xcodeproj``: \n\n- Xcode \"build post-action\" : add extra command below\n \n .. code-block:: bash\n\n $ xunique \"${PODS_ROOT}/Pods.xcodeproj\"\n\n- Git hook: add one more command in hook script\n\n .. code-block:: bash\n\n $ { echo '#!/bin/sh'; echo 'xunique path/to/MyProject.xcodeproj'; echo 'xunique path/to/Pods.xcodeproj'; } > .git/hooks/pre-commit\n\nSupported argument options\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nUse options in xUnique:\n\n.. code-block:: bash\n\n $ xunique [options] \"path_to/YourProject.xcodeproj/or_project.pbxproj\"\n\n-v print verbose output, and generate ``debug_result.json`` file for debug.\n-u uniquify project file, that is, replace UUID to MD5 digest.\n-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.\n-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.\n-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.\n\n**Note**: If neither ``-u`` nor ``-s`` exists, ``-u -s`` will be appended to existing option list.\n\nExamples\n--------\n\n- `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 `__ and try to open and build it in Xcode. You will find that ``xUnique`` does not affect the project at all.\n- The initial diff result could be found `here `__.\n- The diff result with my modified `sort-Xcode-project-file `__ with ``PBXBuildFile`` and ``PBXFileReference`` sort support could be found `here `__.\n- Pure python sort result could be found `here `__\n- PBX sections sorted by MD5 digest result (default in v4.0.0) could be\n found `below `__\n\nadd xUnique to Xcode post action\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n\n.. figure:: https://raw.github.com/truebit/xUnique/gif/xUnique_Build_Post_Action.gif\n :alt: xUnique\\_Build\\_Post\\_Action\n\nNOTICE\n------\n\n- All project members must add the build post-action or git hook. Thus\n the project file would be consistent in the repository.\n- Tested supported ``isa`` types:\n\n - ``PBXProject``\n - ``XCConfigurationList``\n - ``PBXNativeTarget``\n - ``PBXTargetDependency``\n - ``PBXContainerItemProxy``\n - ``XCBuildConfiguration``\n - ``PBXSourcesBuildPhase``\n - ``PBXFrameworksBuildPhase``\n - ``PBXResourcesBuildPhase``\n - ``PBXFrameworksBuildPhase``\n - ``PBXCopyFilesBuildPhase``\n - ``PBXHeadersBuildPhase``\n - ``PBXShellScriptBuildPhase``\n - ``PBXBuildRule``\n - ``PBXBuildFile``\n - ``PBXReferenceProxy``\n - ``PBXFileReference``\n - ``PBXGroup``\n - ``PBXVariantGroup``\n\nAuthors\n-------\n\n- Xiao Wang (`seganw `__)\n\nContributions\n-------------\n\n- I only tested on several single projects and several projects with a\n subproject, so maybe there should be more unconsidered conditions. If\n you get any problem, feel free to fire a Pull Request or Issue\n\n- You can also buy me a cup of tea: |Donate to xUnique|\n\nLicense\n-------\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may\nnot use this file except in compliance with the License. You may obtain\na copy of the License at\n\n::\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n.. |Donate to xUnique| image:: https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif\n :target: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=QQNATFYESVT76&item_name=xUnique", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/truebit/xUnique", "keywords": "Xcode project file,pbxproj,resolve merge conflict", "license": "Apache License, Version 2.0", "maintainer": null, "maintainer_email": null, "name": "xUnique", "package_url": "https://pypi.org/project/xUnique/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/xUnique/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/truebit/xUnique" }, "release_url": "https://pypi.org/project/xUnique/4.1.4/", "requires_dist": null, "requires_python": null, "summary": "A converter of the Xcode project file to make merging it much easier in VCS", "version": "4.1.4" }, "last_serial": 2050911, "releases": { "4.0.2": [ { "comment_text": "", "digests": { "md5": "2b999b4667ae37201f6d56ab7cecc947", "sha256": "f91ae735d9bacd7cb6fe6c452031625d1d89c796f1012678ecbe5a1a5c4b7197" }, "downloads": -1, "filename": "xUnique-4.0.2.tar.gz", "has_sig": false, "md5_digest": "2b999b4667ae37201f6d56ab7cecc947", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10774, "upload_time": "2014-11-26T13:36:45", "url": "https://files.pythonhosted.org/packages/a6/37/76502aaf7a626e9eb7fbc1732a3f6199f33d0136e1d129d537fc335e9a29/xUnique-4.0.2.tar.gz" } ], "4.1.0": [ { "comment_text": "", "digests": { "md5": "75d870d99efd3511fc69419021e9b0ed", "sha256": "95427ba14584e513aa70783f927207772cae1f8c9c6be325fab2820a50b1031a" }, "downloads": -1, "filename": "xUnique-4.1.0.tar.gz", "has_sig": false, "md5_digest": "75d870d99efd3511fc69419021e9b0ed", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10907, "upload_time": "2015-01-16T12:37:37", "url": "https://files.pythonhosted.org/packages/2c/b2/7d9d07e6b6a92d948b8c162b4d63eb653328858334a7b91bf77a78c5e689/xUnique-4.1.0.tar.gz" } ], "4.1.1": [ { "comment_text": "", "digests": { "md5": "998dae2a7a78b09d0e626bca34f1dc11", "sha256": "c0b549d5161cc64955990133183be4052caa127aa6c476b226a1ca0779c549ac" }, "downloads": -1, "filename": "xUnique-4.1.1.tar.gz", "has_sig": false, "md5_digest": "998dae2a7a78b09d0e626bca34f1dc11", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10960, "upload_time": "2015-03-04T02:50:16", "url": "https://files.pythonhosted.org/packages/74/55/29f74a2901039aebb11dadeaef78bd289fc8b3483a2abb7ed015c84b6b7a/xUnique-4.1.1.tar.gz" } ], "4.1.2": [ { "comment_text": "", "digests": { "md5": "c5b61408f9f6d63ec1e1bc74529b8edf", "sha256": "15302dd0f81f1d3a0cb2a596d8a28f4696ce72a5fe387ac13454fd5e60ae55ea" }, "downloads": -1, "filename": "xUnique-4.1.2.tar.gz", "has_sig": false, "md5_digest": "c5b61408f9f6d63ec1e1bc74529b8edf", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11247, "upload_time": "2015-09-06T11:23:33", "url": "https://files.pythonhosted.org/packages/fc/ee/9eeeea0cc1f06e74f5d05883ed9cfcb4445ca7be146ed5b159258fe7c86b/xUnique-4.1.2.tar.gz" } ], "4.1.4": [ { "comment_text": "", "digests": { "md5": "23d6b4d74d17c19e418c0f04d9766b87", "sha256": "69cb36b6998129343f0a851d2542c9aaa590ee253fc22b8b5ed5cd73c70ea68a" }, "downloads": -1, "filename": "xUnique-4.1.4.tar.gz", "has_sig": false, "md5_digest": "23d6b4d74d17c19e418c0f04d9766b87", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11828, "upload_time": "2016-04-07T08:16:54", "url": "https://files.pythonhosted.org/packages/64/e0/bd7e2ce2c78145578eea4c3e8d8cf2cd735545fb03207544e0a44e3410d4/xUnique-4.1.4.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "23d6b4d74d17c19e418c0f04d9766b87", "sha256": "69cb36b6998129343f0a851d2542c9aaa590ee253fc22b8b5ed5cd73c70ea68a" }, "downloads": -1, "filename": "xUnique-4.1.4.tar.gz", "has_sig": false, "md5_digest": "23d6b4d74d17c19e418c0f04d9766b87", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11828, "upload_time": "2016-04-07T08:16:54", "url": "https://files.pythonhosted.org/packages/64/e0/bd7e2ce2c78145578eea4c3e8d8cf2cd735545fb03207544e0a44e3410d4/xUnique-4.1.4.tar.gz" } ] }