aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2021-09-03 16:45:48 +0200
committerStefan Boberg <[email protected]>2021-09-03 16:45:48 +0200
commitcaad16df658eda6dbf2c891c7b055ab08c4f226a (patch)
tree0fa416cffa2c422a53d4ae0087e57f89f315bc92 /scripts
parentSuppressed another clang warning involving unreferenced local variable (diff)
downloadzen-caad16df658eda6dbf2c891c7b055ab08c4f226a.tar.xz
zen-caad16df658eda6dbf2c891c7b055ab08c4f226a.zip
Improvements to build deploy scripts
Deploybuild script now builds code first Jazzed up terminal output
Diffstat (limited to 'scripts')
-rw-r--r--scripts/deploybuild.py31
-rw-r--r--scripts/vswhere.py317
2 files changed, 341 insertions, 7 deletions
diff --git a/scripts/deploybuild.py b/scripts/deploybuild.py
index 1062f8b2e..1d9d5d839 100644
--- a/scripts/deploybuild.py
+++ b/scripts/deploybuild.py
@@ -4,9 +4,14 @@ import os
import fileinput
import colorama
import shutil
+import vswhere
+import subprocess
from peafour import P4
from colorama import Fore, Back, Style
+def jazz_print(tag, detail = ""):
+ print(f"{Fore.WHITE}{Style.BRIGHT}||> {tag}{Style.RESET_ALL} {detail}")
+
colorama.init()
origcwd = os.getcwd()
@@ -31,10 +36,20 @@ zenroot = __file__
while not os.path.exists(os.path.join(zenroot, "zen.sln")):
zenroot = os.path.dirname(zenroot)
-print(f"Zen root: {zenroot}")
+jazz_print("Zen root:", zenroot)
+
+# Build fresh binaries
+
+vs_path = vswhere.get_latest_path() # can also specify prerelease=True
+jazz_print("BUILDING CODE", f"using VS root: {vs_path}")
+devenv_path = os.path.join(vs_path, "Common7\\IDE\\devenv.com")
+
+subprocess.run([devenv_path, "/build", "Release", "zen.sln"])
# Upload symbols etc to Sentry
+jazz_print("Uploading symbols", "to Sentry")
+subprocess.run(["scripts\sentry-cli.exe", "upload-dif", "--org", "to", "--project", "zen-server", "x64\\Release\\zenserver.exe", "x64\\Release\\zenserver.pdb"])
# scripts\sentry-cli.exe upload-dif --org to --project zen-server x64\Release\zenserver.exe x64\Release\zenserver.pdb
# Change into root directory to pick up Perforce environment
@@ -49,7 +64,7 @@ if not os.path.samefile(p4info.clientRoot, engineroot):
# check out the binaries
-print(f"Reverting any previous unsubmitted deploy")
+jazz_print("Reverting", "any previous unsubmitted deploy")
try:
P4.revert("Engine/Binaries/Win64/zenserver.*").run()
@@ -57,7 +72,7 @@ try:
except:
pass
-print(f"Checking out zenserver executables")
+jazz_print("Checking out", "zenserver executables")
try:
P4.edit("Engine/Binaries/Win64/zenserver.*").run()
@@ -65,16 +80,18 @@ try:
except:
pass
-print(f"Placing zenserver executables into tree")
+bin_dir = os.path.join(engineroot, "Engine\\Binaries\\Win64")
+
+jazz_print("Placing zenserver", f"executables into tree at '{bin_dir}'")
crashpadtarget = os.path.join(engineroot, "Engine/Binaries/Win64/crashpad_handler.exe")
try:
- shutil.copy(os.path.join(zenroot, "x64\Release\zenserver.exe"), os.path.join(engineroot, "Engine/Binaries/Win64/zenserver.exe"))
- shutil.copy(os.path.join(zenroot, "x64\Release\zenserver.pdb"), os.path.join(engineroot, "Engine/Binaries/Win64/zenserver.pdb"))
+ shutil.copy(os.path.join(zenroot, "x64\Release\zenserver.exe"), os.path.join(bin_dir, "zenserver.exe"))
+ shutil.copy(os.path.join(zenroot, "x64\Release\zenserver.pdb"), os.path.join(bin_dir, "zenserver.pdb"))
shutil.copy(os.path.join(zenroot, r'vcpkg_installed\x64-windows-static\tools\sentry-native\crashpad_handler.exe'), crashpadtarget)
P4.add(crashpadtarget).run()
- print("All done and good!")
+ jazz_print("All done and good!")
except Exception as e:
print(f"Noooooo: {e.args}")
pass
diff --git a/scripts/vswhere.py b/scripts/vswhere.py
new file mode 100644
index 000000000..82b0723f9
--- /dev/null
+++ b/scripts/vswhere.py
@@ -0,0 +1,317 @@
+r"""
+Interface to Microsoft's Visual Studio locator tool, vswhere.
+
+If Visual Studio 15.2 or later has been installed, this will use the vswhere
+binary installed with Visual Studio. Otherwise, it will download the latest
+release of vswhere from https://github.com/Microsoft/vswhere the first time a
+function is called.
+"""
+
+import json
+import os
+import shutil
+import subprocess
+
+__version__ = '1.3.0'
+__author__ = 'Joel Spadin'
+__license__ = 'MIT'
+
+LATEST_RELEASE_ENDPOINT = 'https://api.github.com/repos/Microsoft/vswhere/releases/latest'
+DOWNLOAD_PATH = os.path.join(os.path.dirname(__file__), 'vswhere.exe')
+
+if 'ProgramFiles(x86)' in os.environ:
+ DEFAULT_PATH = os.path.join(os.environ['ProgramFiles(x86)'], 'Microsoft Visual Studio', 'Installer', 'vswhere.exe')
+else:
+ DEFAULT_PATH = None
+
+alternate_path = None
+download_mirror_url = None
+
+
+def execute(args):
+ """
+ Call vswhere with the given arguments and return an array of results.
+
+ `args` is a list of command line arguments to pass to vswhere.
+
+ If the argument list contains '-property', this returns an array with the
+ property value for each result. Otherwise, this returns an array of
+ dictionaries containing the results.
+ """
+ is_property = '-property' in args
+
+ args = [get_vswhere_path(), '-utf8'] + args
+
+ if not is_property:
+ args.extend(['-format', 'json'])
+
+ output = subprocess.check_output(args).decode('utf-8')
+
+ if is_property:
+ return output.splitlines()
+ else:
+ return json.loads(output)
+
+
+def find(
+ find=None,
+ find_all=False,
+ latest=False,
+ legacy=False,
+ path=None,
+ prerelease=False,
+ products=None,
+ prop=None,
+ requires=None,
+ requires_any=False,
+ sort=False,
+ version=None,
+):
+ """
+ Call vswhere and return an array of the results.
+
+ Selection Options:
+ find_all: If True, finds all instances even if they are incomplete and
+ may not launch.
+ prerelease: If True, also searches prereleases. By default, only
+ releases are searched.
+ products: a product ID or list of one or more product IDs to find.
+ Defaults to Community, Professional, and Enterprise if not specified.
+ Specify '*' by itself to search all product instances installed.
+ See https://aka.ms/vs/workloads for a list of product IDs.
+ requires: a workload component ID or list of one or more IDs required
+ when finding instances. All specified IDs must be installed unless
+ `requires_any` is True. See https://aka.ms/vs/workloads for a list
+ of workload and component IDs.
+ requires_any: If True, find instances with any one or more workload or
+ component IDs passed to `requires`.
+ version: A version range for instances to find. Example: '[15.0,16.0)'
+ will find versions 15.*.
+ latest: If True, returns only the newest version and last installed.
+ legacy: If True, also searches Visual Studio 2015 and older products.
+ Information is limited. This option cannot be used with either
+ `products` or `requires`.
+ path: Gets the instance for the given file path. Not compatible with any
+ other selection option.
+
+ Output Options:
+ sort: If True, sorts the instances from newest version and last installed
+ to oldest. When used with `find`, first instances are sorted, then
+ files are sorted lexigraphically.
+ prop: The name of a property to return instead of the full installation
+ details. Use delimiters '.', '/', or '_' to separate object and
+ property names. Example: 'properties.nickname' will return the
+ 'nickname' property under 'properties'.
+ find: Returns the file paths matching this glob pattern under the
+ installation path. The following patterns are supported:
+ ? Matches any one character except "\\"
+ * Matches zero or more characters except "\\"
+ ** Searches the current directory and subdirectories for the
+ remaining search pattern.
+ """
+ args = []
+
+ if find:
+ args.append('-find')
+ args.append(find)
+
+ if find_all:
+ args.append('-all')
+
+ if latest:
+ args.append('-latest')
+
+ if legacy:
+ args.append('-legacy')
+
+ if path:
+ args.append('-path')
+ args.append(path)
+
+ if prerelease:
+ args.append('-prerelease')
+
+ if products:
+ args.append('-products')
+ _extend_or_append(args, products)
+
+ if prop:
+ args.append('-property')
+ args.append(prop)
+
+ if requires:
+ args.append('-requires')
+ _extend_or_append(args, requires)
+
+ if requires_any:
+ args.append('-requiresAny')
+
+ if sort:
+ args.append('-sort')
+
+ if version:
+ args.append('-version')
+ args.append(version)
+
+ return execute(args)
+
+
+def find_first(**kwargs):
+ """
+ Call vswhere and returns only the first result, or None if there are no results.
+
+ See find() for keyword arguments.
+ """
+ return next(iter(find(**kwargs)), None)
+
+
+def get_latest(legacy=None, **kwargs):
+ """
+ Get the information for the latest installed version of Visual Studio.
+
+ Also supports the same selection options as find(), for example to select
+ different products. If the `legacy` argument is not set, it defaults to
+ `True` unless either `products` or `requires` arguments are set.
+ """
+ legacy = _get_legacy_arg(legacy, **kwargs)
+ return find_first(latest=True, legacy=legacy, **kwargs)
+
+
+def get_latest_path(legacy=None, **kwargs):
+ """
+ Get the file path to the latest installed version of Visual Studio.
+
+ Returns None if no installations could be found.
+
+ Also supports the same selection options as find(), for example to select
+ different products. If the `legacy` argument is not set, it defaults to
+ `True` unless either `products` or `requires` arguments are set.
+ """
+ legacy = _get_legacy_arg(legacy, **kwargs)
+ return find_first(latest=True, legacy=legacy, prop='installationPath', **kwargs)
+
+
+def get_latest_version(legacy=None, **kwargs):
+ """
+ Get the version string of the latest installed version of Visual Studio.
+
+ For Visual Studio 2017 and newer, this is the full version number, for
+ example: '15.8.28010.2003'.
+
+ For Visual Studio 2015 and older, this only contains the major version, with
+ the minor version set to 0, for example: '14.0'.
+
+ Returns None if no installations could be found.
+
+ Also supports the same selection options as find(), for example to select
+ different products. If the `legacy` argument is not set, it defaults to
+ `True` unless either `products` or `requires` arguments are set.
+ """
+ legacy = _get_legacy_arg(legacy, **kwargs)
+ return find_first(latest=True, legacy=legacy, prop='installationVersion', **kwargs)
+
+def get_latest_major_version(**kwargs):
+ """
+ Get the major version of the latest installed version of Visual Studio as an int.
+
+ Returns 0 if no installations could be found.
+
+ Also supports the same selection options as find(), for example to select
+ different products. If the `legacy` argument is not set, it defaults to
+ `True` unless either `products` or `requires` arguments are set.
+ """
+ return int(next(iter(get_latest_version(**kwargs).split('.')), '0'))
+
+
+def get_vswhere_path():
+ """
+ Get the path to vshwere.exe.
+
+ If vswhere is not already installed as part of Visual Studio, and no
+ alternate path is given using `set_vswhere_path()`, the latest release will
+ be downloaded and stored alongside this script.
+ """
+ if alternate_path and os.path.exists(alternate_path):
+ return alternate_path
+
+ if DEFAULT_PATH and os.path.exists(DEFAULT_PATH):
+ return DEFAULT_PATH
+
+ if os.path.exists(DOWNLOAD_PATH):
+ return DOWNLOAD_PATH
+
+ _download_vswhere()
+ return DOWNLOAD_PATH
+
+
+def set_vswhere_path(path):
+ """
+ Set the path to vswhere.exe.
+
+ If this is set, it overrides any version installed as part of Visual Studio.
+ """
+ global alternate_path
+ alternate_path = path
+
+
+def set_download_mirror(url):
+ """
+ Set a URL from which vswhere.exe should be downloaded if it is not already
+ installed as part of Visual Studio and no alternate path is given using
+ `set_vswhere_path()`.
+ """
+ global download_mirror_url
+ download_mirror_url = url
+
+
+def _extend_or_append(lst, value):
+ if isinstance(value, str):
+ lst.append(value)
+ else:
+ lst.extend(value)
+
+
+def _get_legacy_arg(legacy, **kwargs):
+ if legacy is None:
+ return 'products' not in kwargs and 'requires' not in kwargs
+ else:
+ return legacy
+
+
+def _download_vswhere():
+ """
+ Download vswhere to DOWNLOAD_PATH.
+ """
+ print('downloading from', _get_latest_release_url())
+ try:
+ from urllib.request import urlopen
+ with urlopen(_get_latest_release_url()) as response, open(DOWNLOAD_PATH, 'wb') as outfile:
+ shutil.copyfileobj(response, outfile)
+ except ImportError:
+ # Python 2
+ import urllib
+ urllib.urlretrieve(_get_latest_release_url(), DOWNLOAD_PATH)
+
+
+def _get_latest_release_url():
+ """
+ The the URL of the latest release of vswhere.
+ """
+ if download_mirror_url:
+ return download_mirror_url
+
+ try:
+ from urllib.request import urlopen
+ with urlopen(LATEST_RELEASE_ENDPOINT) as response:
+ release = json.loads(response.read(), encoding=response.headers.get_content_charset() or 'utf-8')
+ except ImportError:
+ # Python 2
+ import urllib2
+ response = urllib2.urlopen(LATEST_RELEASE_ENDPOINT)
+ release = json.loads(response.read(), encoding=response.headers.getparam('charset') or 'utf-8')
+
+ for asset in release['assets']:
+ if asset['name'] == 'vswhere.exe':
+ return asset['browser_download_url']
+
+ raise Exception('Could not locate the latest release of vswhere.') \ No newline at end of file