From 348e2cb88119711e8ad9fbb79afb52a6562fb9a7 Mon Sep 17 00:00:00 2001 From: Austin Appleby Date: Mon, 25 Mar 2024 20:14:06 -0700 Subject: [PATCH] tutorials done --- hancho.py | 8 ++++-- tutorial/build.hancho | 17 +++++++---- tutorial/tut5.hancho | 65 +++++++++++++++++++++++++++---------------- 3 files changed, 57 insertions(+), 33 deletions(-) diff --git a/hancho.py b/hancho.py index f054209..64016aa 100755 --- a/hancho.py +++ b/hancho.py @@ -595,7 +595,10 @@ async def run_command(self, command): # Custom commands just get called and then early-out'ed. if callable(command): - return command(self) + result = command(self) + if inspect.isawaitable(result): + result = await(result) + return result # Non-string non-callable commands are not valid if not isinstance(command, str): @@ -741,8 +744,6 @@ async def async_main(self): """All the actual Hancho stuff runs in an async context so that clients can schedule their own async tasks as needed.""" - self.jobs_available = global_config.jobs - # Load the root .hancho files. for file in global_config.start_files: abs_file = global_config.start_path / file @@ -751,6 +752,7 @@ async def async_main(self): self.load_module(abs_file, None) # Root module(s) loaded. Run all tasks in the queue until we run out. + self.jobs_available = global_config.jobs while True: pending_tasks = asyncio.all_tasks() - {asyncio.current_task()} if not pending_tasks: diff --git a/tutorial/build.hancho b/tutorial/build.hancho index bb59fbc..43fa237 100644 --- a/tutorial/build.hancho +++ b/tutorial/build.hancho @@ -1,13 +1,18 @@ # hancho/tutorial/build.hancho - Tests all the tutorials from hancho import * -config.jobs = 1 -#config.verbose = True +global_config.jobs = 1 -test_build = Rule( - desc = "{color(200, 200, 100)}Testing tutorial build '{files_in}'{color()}", - command = "python3 ../hancho.py --verbose {files_in} && echo pass > {files_out} && echo", - files_out = "{files_in[0] + '.pass'}", +build_config.set_defaults( + command_path = Path.cwd(), + source_path = Path.cwd(), + build_path = Path.cwd() / "build" +) + +test_build = build_config.rule( + desc = "{color(200, 200, 100)}Testing tutorial build '{rel_source_files}'{color()}", + command = "python3 ../hancho.py --verbose {rel_source_files} && echo pass > {rel_build_files} && echo", + build_files = "{swap_ext(source_files, '.pass')}", ) test_build("tut0.hancho") diff --git a/tutorial/tut5.hancho b/tutorial/tut5.hancho index 3194b56..b607d79 100644 --- a/tutorial/tut5.hancho +++ b/tutorial/tut5.hancho @@ -2,33 +2,50 @@ from hancho import * import asyncio -config.build_dir = "build/tut4" +build_config.set_defaults( + command_path = Path.cwd(), + source_path = Path.cwd(), + build_path = Path.cwd() / "build/tut5" +) + +# Synchronous functions can be used in place of command strings. + +def sync_callback(task): + print("Sync callback begin") + for abs_file in task.abs_build_files: + print(f"Writing {abs_file}") + with open(abs_file, 'w', encoding="utf-8") as file: + file.write("hello world") + print("Sync callback end") + return task.abs_build_files + +fast_task = build_config.rule(command = sync_callback) +fast_task(["src/main.cpp"], ["fast1.txt", "fast2.txt", "fast3.txt"]) + +# Asynchronous functions can also be used in place of command strings. -# Functions (synchronous or asynchronous) that return filenames or arrays of -# filenames can be used in place of actual filenames in rules. +async def async_callback(task): + print("Async callback begin") + for abs_file in task.abs_build_files: + print(f"Writing {abs_file}") + with open(abs_file, 'w', encoding="utf-8") as file: + file.write("hello world") + await asyncio.sleep(0.1) + print("Async callback end") + return task.abs_build_files -async def do_slow_thing(): - print("Doing slow thing") +slow_task = build_config.rule(command = async_callback) +slow_task(["src/main.cpp"], ["slow1.txt", "slow2.txt", "slow3.txt"]) + +# Promises that resolve to filenames can be used in place of actual filenames in rules. + +async def slow_filename_promise(): + print("Slow promise begin") await asyncio.sleep(0.1) - print("Slow thing done") + print("Slow promise end") return ["src/main.cpp"] -echo = Rule( - desc = "Consuming a promise as files_in", - command = "echo {files_in}", +echo = build_config.rule( + command = "echo {rel_source_files} > {rel_build_files}", ) -echo(do_slow_thing(), []) - -# You can also use them in the command field. -def custom_command(task): - for f in task.files_out: - with open(f, "a", encoding="utf-8") as file: - file.write("asdf\n") - return task.files_out - -custom_rule = Rule( - desc = "Custom rule: {files_in} -> {files_out}", - command = custom_command -) - -custom_rule("src/main.cpp", ["tut4/custom1", "tut4/custom2"]) +echo([slow_filename_promise()], ["promise1.txt"])