| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 | 
							- #!/usr/bin/env python
 
- candidate_paths = "bin obs-plugins data".split()
 
- plist_path = "../cmake/osxbundle/Info.plist"
 
- icon_path = "../cmake/osxbundle/obs.icns"
 
- run_path = "../cmake/osxbundle/obslaunch.sh"
 
- #not copied
 
- blacklist = """/usr /System""".split()
 
- #copied
 
- whitelist = """/usr/local""".split()
 
- #
 
- #
 
- #
 
- from sys import argv
 
- from glob import glob
 
- from subprocess import check_output, call
 
- from collections import namedtuple
 
- from shutil import copy, copytree, rmtree
 
- from os import makedirs, rename, walk, path as ospath
 
- import plistlib
 
- import argparse
 
- def _str_to_bool(s):
 
-     """Convert string to bool (in argparse context)."""
 
-     if s.lower() not in ['true', 'false']:
 
-         raise ValueError('Need bool; got %r' % s)
 
-     return {'true': True, 'false': False}[s.lower()]
 
- def add_boolean_argument(parser, name, default=False):
 
-     """Add a boolean argument to an ArgumentParser instance."""
 
-     group = parser.add_mutually_exclusive_group()
 
-     group.add_argument(
 
-         '--' + name, nargs='?', default=default, const=True, type=_str_to_bool)
 
-     group.add_argument('--no' + name, dest=name, action='store_false')
 
- parser = argparse.ArgumentParser(description='obs-studio package util')
 
- parser.add_argument('-d', '--base-dir', dest='dir', default='rundir/RelWithDebInfo')
 
- parser.add_argument('-n', '--build-number', dest='build_number', default='0')
 
- parser.add_argument('-k', '--public-key', dest='public_key', default='OBSPublicDSAKey.pem')
 
- parser.add_argument('-f', '--sparkle-framework', dest='sparkle', default=None)
 
- parser.add_argument('-b', '--base-url', dest='base_url', default='https://obsproject.com/osx_update')
 
- parser.add_argument('-u', '--user', dest='user', default='jp9000')
 
- parser.add_argument('-c', '--channel', dest='channel', default='master')
 
- add_boolean_argument(parser, 'stable', default=False)
 
- parser.add_argument('-p', '--prefix', dest='prefix', default='')
 
- args = parser.parse_args()
 
- def cmd(cmd):
 
-     import subprocess
 
-     import shlex
 
-     return subprocess.check_output(shlex.split(cmd)).rstrip('\r\n')
 
- LibTarget = namedtuple("LibTarget", ("path", "external", "copy_as"))
 
- inspect = list()
 
- inspected = set()
 
- build_path = args.dir
 
- build_path = build_path.replace("\\ ", " ")
 
- def add(name, external=False, copy_as=None):
 
- 	if external and copy_as is None:
 
- 		copy_as = name.split("/")[-1]
 
- 	if name[0] != "/":
 
- 		name = build_path+"/"+name
 
- 	t = LibTarget(name, external, copy_as)
 
- 	if t in inspected:
 
- 		return
 
- 	inspect.append(t)
 
- 	inspected.add(t)
 
- for i in candidate_paths:
 
- 	print("Checking " + i)
 
- 	for root, dirs, files in walk(build_path+"/"+i):
 
- 		for file_ in files:
 
- 			if ".ini" in file_:
 
- 				continue
 
- 			if ".png" in file_:
 
- 				continue
 
- 			if ".effect" in file_:
 
- 				continue
 
- 			if ".py" in file_:
 
- 				continue
 
- 			if ".json" in file_:
 
- 				continue
 
- 			path = root + "/" + file_
 
- 			try:
 
- 				out = check_output("{0}otool -L '{1}'".format(args.prefix, path), shell=True,
 
- 						universal_newlines=True)
 
- 				if "is not an object file" in out:
 
- 					continue
 
- 			except:
 
- 				continue
 
- 			rel_path = path[len(build_path)+1:]
 
- 			print(repr(path), repr(rel_path))
 
- 			add(rel_path)
 
- def add_plugins(path, replace):
 
- 	for img in glob(path.replace(
 
- 		"lib/QtCore.framework/Versions/5/QtCore",
 
- 		"plugins/%s/*"%replace).replace(
 
- 			"Library/Frameworks/QtCore.framework/Versions/5/QtCore",
 
- 			"share/qt5/plugins/%s/*"%replace)):
 
- 		if "_debug" in img:
 
- 			continue
 
- 		add(img, True, img.split("plugins/")[-1])
 
- actual_sparkle_path = '@loader_path/Frameworks/Sparkle.framework/Versions/A/Sparkle'
 
- while inspect:
 
- 	target = inspect.pop()
 
- 	print("inspecting", repr(target))
 
- 	path = target.path
 
- 	if path[0] == "@":
 
- 		continue
 
- 	out = check_output("{0}otool -L '{1}'".format(args.prefix, path), shell=True,
 
- 			universal_newlines=True)
 
- 	if "QtCore" in path:
 
- 		add_plugins(path, "platforms")
 
- 		add_plugins(path, "imageformats")
 
- 		add_plugins(path, "accessible")
 
- 		add_plugins(path, "styles")
 
- 	for line in out.split("\n")[1:]:
 
- 		new = line.strip().split(" (")[0]
 
- 		if '@' in new and "sparkle.framework" in new.lower():
 
- 			actual_sparkle_path = new
 
- 			print "Using sparkle path:", repr(actual_sparkle_path)
 
- 		if not new or new[0] == "@" or new.endswith(path.split("/")[-1]):
 
- 			continue
 
- 		whitelisted = False
 
- 		for i in whitelist:
 
- 			if new.startswith(i):
 
- 				whitelisted = True
 
- 		if not whitelisted:
 
- 			blacklisted = False
 
- 			for i in blacklist:
 
- 				if new.startswith(i):
 
- 					blacklisted = True
 
- 					break
 
- 			if blacklisted:
 
- 				continue
 
- 		add(new, True)
 
- changes = list()
 
- for path, external, copy_as in inspected:
 
- 	if not external:
 
- 		continue #built with install_rpath hopefully
 
- 	changes.append("-change '%s' '@rpath/%s'"%(path, copy_as))
 
- changes = " ".join(changes)
 
- info = plistlib.readPlist(plist_path)
 
- latest_tag = cmd('git describe --tags --abbrev=0')
 
- log = cmd('git log --pretty=oneline {0}...HEAD'.format(latest_tag))
 
- from os import path
 
- # set version
 
- if args.stable:
 
-     info["CFBundleVersion"] = latest_tag
 
-     info["CFBundleShortVersionString"] = latest_tag
 
-     info["SUFeedURL"] = '{0}/stable/updates.xml'.format(args.base_url)
 
- else:
 
-     info["CFBundleVersion"] = args.build_number
 
-     info["CFBundleShortVersionString"] = '{0}.{1}'.format(latest_tag, args.build_number)
 
-     info["SUFeedURL"] = '{0}/{1}/{2}/updates.xml'.format(args.base_url, args.user, args.channel)
 
- info["SUPublicDSAKeyFile"] = path.basename(args.public_key)
 
- info["OBSFeedsURL"] = '{0}/feeds.xml'.format(args.base_url)
 
- app_name = info["CFBundleName"]+".app"
 
- icon_file = "tmp/Contents/Resources/%s"%info["CFBundleIconFile"]
 
- copytree(build_path, "tmp/Contents/Resources/", symlinks=True)
 
- copy(icon_path, icon_file)
 
- plistlib.writePlist(info, "tmp/Contents/Info.plist")
 
- makedirs("tmp/Contents/MacOS")
 
- copy(run_path, "tmp/Contents/MacOS/%s"%info["CFBundleExecutable"])
 
- try:
 
- 	copy(args.public_key, "tmp/Contents/Resources")
 
- except:
 
- 	pass
 
- if args.sparkle is not None:
 
-     copytree(args.sparkle, "tmp/Contents/Frameworks/Sparkle.framework", symlinks=True)
 
- prefix = "tmp/Contents/Resources/"
 
- sparkle_path = '@loader_path/{0}/Frameworks/Sparkle.framework/Versions/A/Sparkle'
 
- cmd('{0}install_name_tool -change {1} {2} {3}/bin/obs'.format(
 
-     args.prefix, actual_sparkle_path, sparkle_path.format('../..'), prefix))
 
- for path, external, copy_as in inspected:
 
- 	id_ = ""
 
- 	filename = path
 
- 	rpath = ""
 
- 	if external:
 
- 		if copy_as == "Python":
 
- 			continue
 
- 		id_ = "-id '@rpath/%s'"%copy_as
 
- 		filename = prefix + "bin/" +copy_as
 
- 		rpath = "-add_rpath @loader_path/ -add_rpath @executable_path/"
 
- 		if "/" in copy_as:
 
- 			try:
 
- 				dirs = copy_as.rsplit("/", 1)[0]
 
- 				makedirs(prefix + "bin/" + dirs)
 
- 			except:
 
- 				pass
 
- 		copy(path, filename)
 
- 	else:
 
- 		filename = path[len(build_path)+1:]
 
- 		id_ = "-id '@rpath/../%s'"%filename
 
- 		if not filename.startswith("bin"):
 
- 			print(filename)
 
- 			rpath = "-add_rpath '@loader_path/{}/'".format(ospath.relpath("bin/", ospath.dirname(filename)))
 
- 		filename = prefix + filename
 
- 	cmd = "{0}install_name_tool {1} {2} {3} '{4}'".format(args.prefix, changes, id_, rpath, filename)
 
- 	call(cmd, shell=True)
 
- try:
 
- 	rename("tmp", app_name)
 
- except:
 
- 	print("App already exists")
 
- 	rmtree("tmp")
 
 
  |