From 570a33a0e1f3c546b608b4530faecc0404eb42e5 Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Wed, 9 Aug 2023 20:14:59 -0500 Subject: [PATCH 1/4] Dodge AppData problems on Windows (#32) --- scripts/dev.py | 16 ++++++++++++++-- scripts/mkdir.bat | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 scripts/mkdir.bat diff --git a/scripts/dev.py b/scripts/dev.py index 4024fdd..12b875e 100644 --- a/scripts/dev.py +++ b/scripts/dev.py @@ -1,4 +1,3 @@ -import argparse from datetime import datetime import glob import os @@ -506,12 +505,25 @@ def install(args): bin_dir = os.path.join(dest, "bin") yeet(bin_dir) + + # The MS Store version of Python does some really stupid stuff with AppData: + # https://git.handmade.network/hmn/orca/issues/32 + # + # Any new files and folders created in AppData actually get created in a special + # folder specific to the Python version. However, if the files or folders already + # exist, the redirect does not happen. So, if we first use the shell to create the + # paths we need, the following scripts work regardless of Python install. + # + # Also apparently you can't just do mkdir in a subprocess call here, hence the + # trivial batch script. + if platform.system() == "Windows": + subprocess.run(["scripts\\mkdir.bat", bin_dir], check=True) + shutil.copytree("scripts", os.path.join(bin_dir, "sys_scripts")) shutil.copy("orca", bin_dir) if platform.system() == "Windows": shutil.copy("orca.bat", bin_dir) - # TODO: Customize these instructions for Windows print() if platform.system() == "Windows": print("The Orca tools have been installed. Make sure the Orca tools are on your PATH by") diff --git a/scripts/mkdir.bat b/scripts/mkdir.bat new file mode 100644 index 0000000..17cb6f0 --- /dev/null +++ b/scripts/mkdir.bat @@ -0,0 +1,3 @@ +@echo off +mkdir %1 +exit /b %errorlevel% From 50f6ed8bec7b52889afc03e2863d4670a59472c5 Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Wed, 9 Aug 2023 21:41:08 -0500 Subject: [PATCH 2/4] Automatically add Orca to the PATH on Windows --- scripts/dev.py | 33 +++++++++++++++++++++------------ scripts/updatepath.ps1 | 11 +++++++++++ 2 files changed, 32 insertions(+), 12 deletions(-) create mode 100644 scripts/updatepath.ps1 diff --git a/scripts/dev.py b/scripts/dev.py index 12b875e..b158a15 100644 --- a/scripts/dev.py +++ b/scripts/dev.py @@ -484,6 +484,17 @@ def yeet(path): shutil.rmtree(path) +def prompt(msg): + while True: + answer = input(f"{msg} (y/n)> ") + if answer.lower() in ["y", "yes"]: + return True + elif answer.lower() in ["n", "no"]: + return False + else: + print("Please enter \"yes\" or \"no\" and press return.") + + def install(args): if platform.system() == "Windows": dest = os.path.join(os.getenv("LOCALAPPDATA"), "orca") @@ -494,14 +505,8 @@ def install(args): print("The Orca command-line tools will be installed to:") print(dest) print() - while True: - answer = input("Proceed with the installation? (y/n) >") - if answer.lower() in ["y", "yes"]: - break - elif answer.lower() in ["n", "no"]: - return - else: - print("Please enter \"yes\" or \"no\" and press return.") + if not prompt("Proceed with the installation?"): + return bin_dir = os.path.join(dest, "bin") yeet(bin_dir) @@ -526,12 +531,16 @@ def install(args): print() if platform.system() == "Windows": - print("The Orca tools have been installed. Make sure the Orca tools are on your PATH by") - print("adding the following path to your system PATH variable:") - print() + print("The Orca tools have been installed to the following directory:") print(bin_dir) print() - print("You can do this in the Windows settings by searching for \"environment variables\".") + print("The tools will need to be on your PATH in order to actually use them.") + if prompt("Would you like to automatically add Orca to your PATH?"): + subprocess.run(["powershell", "scripts\\updatepath.ps1", bin_dir], check=True) + print("Orca has been added to your PATH. Restart any open terminals to use it.") + else: + print("No worries. You can manually add Orca to your PATH in the Windows settings") + print("this in the Windows settings by searching for \"environment variables\".") else: print("The Orca tools have been installed. Make sure the Orca tools are on your PATH by") print("adding the following to your shell config:") diff --git a/scripts/updatepath.ps1 b/scripts/updatepath.ps1 new file mode 100644 index 0000000..27edb29 --- /dev/null +++ b/scripts/updatepath.ps1 @@ -0,0 +1,11 @@ +param ( + [parameter(Mandatory=$true)] + [string]$orcaPath +) + +$arrPath = [System.Environment]::GetEnvironmentVariable('PATH', 'User') -split ';' +$arrPath = $arrPath | Where-Object { $_ -ne $orcaPath } | Where-Object { $_ -ne '' } +$newPath = ($arrPath + $orcaPath) -join ';' + +[System.Environment]::SetEnvironmentVariable('PATH', $newPath, 'User') +# echo $newPath From 4ae8bc3bfa1090cbb0eeb856243ec000c54e94af Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Wed, 16 Aug 2023 18:49:13 -0500 Subject: [PATCH 3/4] Put gles_gen.log in the build folder --- .gitignore | 1 - scripts/gles_gen.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index c9fb766..678c437 100644 --- a/.gitignore +++ b/.gitignore @@ -28,7 +28,6 @@ src/orca_surface.c src/graphics/orca_gl31.h *bind_gen.c *_stubs.c -gles_gen.log .vscode/launch.json .vscode/settings.json diff --git a/scripts/gles_gen.py b/scripts/gles_gen.py index cb3377e..2d91969 100644 --- a/scripts/gles_gen.py +++ b/scripts/gles_gen.py @@ -32,7 +32,7 @@ def gen_gles_header(spec, filename): tree = et.parse(spec) reg.loadElementTree(tree) - logFile = open('./gles_gen.log', 'w') + logFile = open('./build/gles_gen.log', 'w') gen = COutputGenerator(diagFile=logFile) reg.setGenerator(gen) reg.apiGen(genOpts) From 18069fbc586684e9ce542b80dc94171a241d13c5 Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Wed, 16 Aug 2023 19:58:52 -0500 Subject: [PATCH 4/4] Detect Orca source from anywhere and make scripts work from anywhere --- orca | 45 ++++++++++++++++++++++++++++++++------------ scripts/dev.py | 51 ++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 74 insertions(+), 22 deletions(-) diff --git a/orca b/orca index 17ee216..b5ae866 100755 --- a/orca +++ b/orca @@ -7,24 +7,45 @@ import os import sys -root = True -try: - os.stat(".orcaroot") -except FileNotFoundError: - root = False +if __name__ != "__main__": + print("why are you importing the orca command-line tool as a Python module, you absolute goofball") + exit(1) -if root: - # Running from Orca source checkout; use local source's scripts. - scriptdir = os.path.dirname(os.path.abspath(__file__)) - if scriptdir != os.getcwd(): - # Only print this warning if running the system-installed Orca. - # It's annoying to see this if you run ./orca from the source. +# If you modify this, be sure to modify the version in scripts/dev.py as well. +def check_if_source(): + def path_is_in_orca_source(path): + dir = path + while True: + try: + os.stat(os.path.join(dir, ".orcaroot")) + return (True, dir) + except FileNotFoundError: + pass + + newdir = os.path.dirname(dir) + if newdir == dir: + return (False, None) + dir = newdir + + in_source, current_source_dir = path_is_in_orca_source(os.getcwd()) + script_is_source, script_source_dir = path_is_in_orca_source(os.path.dirname(os.path.abspath(__file__))) + + use_source = in_source or script_is_source + source_dir = current_source_dir or script_source_dir + return (use_source, source_dir, script_is_source) + + +use_source, source_dir, is_source = check_if_source() +if use_source: + # Use the source checkout's scripts instead of the system-installed scripts. + + if not is_source: print("The Orca tool is running from a local source checkout and will") print("use that instead of the system Orca installation.") print() - sys.path.append(os.getcwd()) + sys.path.append(source_dir) import scripts.orca else: # Running from outside Orca source checkout; use system Orca install. diff --git a/scripts/dev.py b/scripts/dev.py index b158a15..e465ea9 100644 --- a/scripts/dev.py +++ b/scripts/dev.py @@ -19,9 +19,9 @@ ANGLE_VERSION = "2023-07-05" def attach_dev_commands(subparsers): dev_cmd = subparsers.add_parser("dev", help="Commands for building Orca itself. Must be run from the root of an Orca source checkout.") - dev_cmd.set_defaults(func=orca_root_only) + dev_cmd.set_defaults(func=orca_source_only) - dev_sub = dev_cmd.add_subparsers(required=is_orca_root(), title='commands') + dev_sub = dev_cmd.add_subparsers(required=is_orca_source(), title='commands') build_cmd = dev_sub.add_parser("build-runtime", help="Build the Orca runtime from source.") build_cmd.add_argument("--release", action="store_true", help="compile Orca in release mode (default is debug)") @@ -35,15 +35,39 @@ def attach_dev_commands(subparsers): install_cmd.set_defaults(func=dev_shellish(install)) -def is_orca_root(): - try: - os.stat(".orcaroot") - return True - except FileNotFoundError: - return False +# Checks if the Orca tool should use a source checkout of Orca instead of a system install. +# This is copy-pasted to the command-line tool so it can work before loading anything. +# +# Returns: (use source, source directory, is actually the source's tool) +def check_if_source(): + def path_is_in_orca_source(path): + dir = path + while True: + try: + os.stat(os.path.join(dir, ".orcaroot")) + return (True, dir) + except FileNotFoundError: + pass + + newdir = os.path.dirname(dir) + if newdir == dir: # TODO: Verify on Windows (it will probably not work) + return (False, None) + dir = newdir + + in_source, current_source_dir = path_is_in_orca_source(os.getcwd()) + script_is_source, script_source_dir = path_is_in_orca_source(os.path.dirname(os.path.abspath(__file__))) + + use_source = in_source or script_is_source + source_dir = current_source_dir or script_source_dir + return (use_source, source_dir, script_is_source) -def orca_root_only(args): +def is_orca_source(): + use_source, _, _ = check_if_source() + return use_source + + +def orca_source_only(args): print("The Orca dev commands can only be run from an Orca source checkout.") print() print("If you want to build Orca yourself, download the source here:") @@ -52,7 +76,14 @@ def orca_root_only(args): def dev_shellish(func): - return shellish(func) if is_orca_root() else orca_root_only + use_source, source_dir, _ = check_if_source() + if not use_source: + return orca_source_only + + def func_from_source(args): + os.chdir(source_dir) + func(args) + return shellish(func_from_source) def build_runtime(args):