Skip to content

Instantly share code, notes, and snippets.

@sttz
Created June 6, 2017 18:15
Show Gist options
  • Save sttz/f0322740c39336ca3740ac7a92273481 to your computer and use it in GitHub Desktop.
Save sttz/f0322740c39336ca3740ac7a92273481 to your computer and use it in GitHub Desktop.
Wrapper that finds the latest UnityYAMLMerge installed on your Mac
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# The MIT License (MIT)
#
# Copyright (c) 2017 Adrian Stutz
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#### Introduction ####
#
# Unity provides the UnityYAMLMerge merge tool to intelligently merge Unity's
# YAML-based text asset files.
#
# The merge tool needs to be configured with your version control software and
# they usually require an absolute path to the merge tool.
# However, many people have multiple versions of Unity installed and so the
# path of the Unity installation and with it the the path to the merge tool can
# change at any time.
#
# This script can be used as a proxy between your version control software
# and the merge tool installed with Unity. The script looks for the latest
# Unity installation on your system and then forwards the call to the
# merge tool.
import os.path
import re
import subprocess
import sys
# Bundle ID that will be looked up via Spotlight to find Unity installs
# (note that Unity 2017 still has the same bundle id)
UNITY_BUNDLE_ID = "com.unity3d.UnityEditor5.x"
# Regex to match Unity version from full version string, e.g. "Unity version 2017.1.0b7"
VERSION_RE = "(\d+)\.(\d+)\.(\d+)(\w)(\d+)"
# Sorting strength for release type letters in versions
RELEASE_LETTER_STRENGTH = { 'f': 1, 'p': 2, 'b': 3, 'a': 4 }
# Sub-path to the merge tool executable from the Unity.app bundle
MERGE_TOOL_PATH = "/Contents/Tools/UnityYAMLMerge"
# Parse a version string and return a list with the individual version numbers
def parse_version(version):
match = re.search(VERSION_RE, version)
if not match:
print 'Version %s does not conform to Unity version format 0.0.0x0' % version
sys.exit(1)
parts = list(match.groups())
# Convert to int, except fourth element wich is release type letter
for i in range(len(parts)):
if not parts[i] or i == 3: continue
parts[i] = int(parts[i])
if parts[3]:
if not parts[3] in RELEASE_LETTER_STRENGTH:
print 'Unknown release letter "%s" from "%s"' % (parts[3], version)
sys.exit(1)
parts[3] = RELEASE_LETTER_STRENGTH[parts[3]]
else:
parts[3] = RELEASE_LETTER_STRENGTH['f']
return parts
def compare_versions(one, two):
return cmp(parse_version(one["version"]), parse_version(two["version"]))
# Use spotlight to find Unity installations
command = "mdfind kMDItemCFBundleIdentifier = '%s'" % UNITY_BUNDLE_ID
data = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE).stdout.read()
# Validate installations
paths = filter(None, data.split("\n"))
installs = []
for path in paths:
# Get and check the Unity version string
command = "mdls -name kMDItemVersion -r '%s'" % path
data = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE).stdout.read()
match = re.search(VERSION_RE, data)
if not match:
print "WARNING: Could not parse Unity version string '%s' at path '%s'" % (data, path)
continue
# Unity < 5 didn't yet include the merge tool
if int(match.group(1)) < 5:
continue
# Check if the tool exists at the expected path
tool_path = path + MERGE_TOOL_PATH
if not os.path.isfile(tool_path):
print "WARNING: Unity installation '%s' does not contain merge tool at '%s'" % (path, tool_path)
continue
installs.append({
"version": data,
"path": tool_path
})
if len(installs) == 0:
print "ERROR: No Unity installation found"
sys.exit(1)
# Use the merge tool from the newest Unity version
installs = sorted(installs, compare_versions)
path = installs[0]["path"]
# Wrap the merge tool, connecting our stdin, stdout and stderr
p = subprocess.Popen([path] + sys.argv[1:], stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr)
p.wait()
sys.exit(p.returncode)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment