From 860ee2d8b9f753a8a3f2b99818a4a1bcecf64ab6 Mon Sep 17 00:00:00 2001 From: anurag Date: Tue, 25 Aug 2026 16:17:41 -0600 Subject: [PATCH 1/3] add version at build Signed-off-by: anurag --- pyproject.toml | 4 +++ setup.py | 74 ++++++++++++++++++++++++++++++++++++++ src/mldebug/_build_info.py | 11 ++++++ src/mldebug/mldebug_cli.py | 9 ++++- src/mldebug/utils.py | 17 +++++++-- 5 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 setup.py create mode 100644 src/mldebug/_build_info.py diff --git a/pyproject.toml b/pyproject.toml index 2c657cc..c3333ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,7 @@ +[build-system] +requires = ["setuptools>=77"] +build-backend = "setuptools.build_meta" + [project] name = "mldebug_xdp" version = "0.1.0" diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..cb51489 --- /dev/null +++ b/setup.py @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2024-2025 Advanced Micro Devices, Inc. All rights reserved. + +""" +Stamps the git commit into the built package. All metadata lives in pyproject.toml. +""" + +from datetime import datetime, timezone +from pathlib import Path + +import os +import subprocess + +from setuptools import setup +from setuptools.command.build_py import build_py + +ROOT = Path(__file__).parent.resolve() + + +def _git(*args): + """ + Run a git command in the source tree, returning "" on any failure. + """ + try: + out = subprocess.run( + ["git", "-C", str(ROOT), *args], capture_output=True, text=True, check=True, timeout=5 + ) + except (OSError, subprocess.SubprocessError): + return "" + return out.stdout.strip() + + +def _commit(): + """ + Full HEAD commit. Falls back to GITHUB_SHA when building without a .git dir. + """ + commit = _git("rev-parse", "HEAD") or os.environ.get("GITHUB_SHA", "") + if not commit: + return "" + # Scoped to *.py: the LFS binaries under bin/ and backend/ routinely show as + # modified after a smudge, which would mark every build dirty. + if _git("status", "--porcelain", "--", "*.py"): + commit += "-dirty" + return commit + + +def _write_stamp(build_lib, version): + """ + Overwrite mldebug/_build_info.py in the build tree with the version and commit. + """ + commit = _commit() + stamp = Path(build_lib) / "mldebug" / "_build_info.py" + build_date = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%SZ") + stamp.write_text( + '"""Generated at build time by setup.py."""\n\n' + f'VERSION = "{version}"\n' + f'COMMIT = "{commit}"\n' + f'BUILD_DATE = "{build_date}"\n', + encoding="utf-8", + ) + print(f"[INFO] stamped {stamp} with commit '{commit}'") + + +class BuildPyStamped(build_py): + """ + Stamp the build tree after the sources are copied, leaving the source tree untouched. + """ + + def run(self): + super().run() + _write_stamp(self.build_lib, self.distribution.get_version()) + + +setup(cmdclass={"build_py": BuildPyStamped}) diff --git a/src/mldebug/_build_info.py b/src/mldebug/_build_info.py new file mode 100644 index 0000000..c62fb5f --- /dev/null +++ b/src/mldebug/_build_info.py @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2024-2025 Advanced Micro Devices, Inc. All rights reserved. + +""" +Build stamp. setup.py overwrites this inside the built package. +Values stay empty when running from a source tree. +""" + +VERSION = "" +COMMIT = "" +BUILD_DATE = "" diff --git a/src/mldebug/mldebug_cli.py b/src/mldebug/mldebug_cli.py index 2c54fd5..d2d5182 100644 --- a/src/mldebug/mldebug_cli.py +++ b/src/mldebug/mldebug_cli.py @@ -31,7 +31,7 @@ create_run_flags, ) from mldebug.interactive_prompt import InteractivePrompt -from mldebug.utils import setup_logger, close_logger, is_windows +from mldebug.utils import LOGGER, setup_logger, close_logger, is_windows, version_string def _apply_unsupported_kernels_from_args(args): @@ -220,6 +220,12 @@ def app(): top_msg = "AIE Debug for VAIML.\nDefault data dump mode is binary. Files have 8byte header specifying total bytes." p = argparse.ArgumentParser(description=top_msg, formatter_class=RawTextHelpFormatter) + p.add_argument( + "--version", + action="version", + version=version_string(), + help="Show version and the commit this build came from, then exit.\n", + ) p.add_argument( "-b", "--buffer_info", @@ -410,6 +416,7 @@ def app(): ) args = p.parse_args() setup_logger(args) + LOGGER.log(f"[INFO] {version_string()}") if not check_args(args): print("Argument check failed") diff --git a/src/mldebug/utils.py b/src/mldebug/utils.py index 0623dd0..2574653 100644 --- a/src/mldebug/utils.py +++ b/src/mldebug/utils.py @@ -5,13 +5,14 @@ Helpful utilities like logging """ -from pathlib import Path - import os import platform import sys import threading import time +from pathlib import Path + +from mldebug import _build_info class Logger: @@ -106,6 +107,18 @@ def close_logger(): LOGGER.close() +def version_string(): + """ + One line banner: version, commit and build date of the installed package. + """ + if not _build_info.COMMIT: + return "mldebug (running from source, no build stamp)" + return ( + f"mldebug {_build_info.VERSION} (commit {_build_info.COMMIT})" + f" built {_build_info.BUILD_DATE}" + ) + + class Version: """ Simple versioning class for (major, minor) version management. From 1a988c04483306e94051a497375bca742eec7d3c Mon Sep 17 00:00:00 2001 From: anurag Date: Tue, 25 Aug 2026 16:30:21 -0600 Subject: [PATCH 2/3] use uv build Signed-off-by: anurag --- setup.py | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/setup.py b/setup.py index cb51489..9f2958e 100644 --- a/setup.py +++ b/setup.py @@ -13,6 +13,7 @@ from setuptools import setup from setuptools.command.build_py import build_py +from setuptools.command.sdist import sdist ROOT = Path(__file__).parent.resolve() @@ -37,20 +38,26 @@ def _commit(): commit = _git("rev-parse", "HEAD") or os.environ.get("GITHUB_SHA", "") if not commit: return "" - # Scoped to *.py: the LFS binaries under bin/ and backend/ routinely show as - # modified after a smudge, which would mark every build dirty. - if _git("status", "--porcelain", "--", "*.py"): + # Scoped to tracked *.py: the LFS binaries under bin/ and backend/ show as modified + # after a smudge, and sdist leaves an untracked copy of the tree behind while it runs. + if _git("status", "--porcelain", "-uno", "--", "*.py"): commit += "-dirty" return commit -def _write_stamp(build_lib, version): +def _write_stamp(stamp, version): """ - Overwrite mldebug/_build_info.py in the build tree with the version and commit. + Write _build_info.py, or keep the existing one when the commit is unknown. + An unknown commit means we are building from an sdist, which already carries + the stamp written when the sdist itself was built. """ commit = _commit() - stamp = Path(build_lib) / "mldebug" / "_build_info.py" + if not commit: + print(f"[WARNING] no git commit found, leaving {stamp} as is") + return build_date = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%SZ") + # sdist hard links files out of the source tree, so replace instead of writing in place. + stamp.unlink(missing_ok=True) stamp.write_text( '"""Generated at build time by setup.py."""\n\n' f'VERSION = "{version}"\n' @@ -68,7 +75,19 @@ class BuildPyStamped(build_py): def run(self): super().run() - _write_stamp(self.build_lib, self.distribution.get_version()) + stamp = Path(self.build_lib) / "mldebug" / "_build_info.py" + _write_stamp(stamp, self.distribution.get_version()) + + +class SdistStamped(sdist): + """ + Stamp the sdist so a wheel built from it keeps the commit. + """ + + def make_release_tree(self, base_dir, files): + super().make_release_tree(base_dir, files) + stamp = Path(base_dir) / "src" / "mldebug" / "_build_info.py" + _write_stamp(stamp, self.distribution.get_version()) -setup(cmdclass={"build_py": BuildPyStamped}) +setup(cmdclass={"build_py": BuildPyStamped, "sdist": SdistStamped}) From 49472cd87bc77c93c80f105a713a327501c6a7c8 Mon Sep 17 00:00:00 2001 From: anurag Date: Tue, 25 Aug 2026 16:35:17 -0600 Subject: [PATCH 3/3] simple msg Signed-off-by: anurag --- src/mldebug/mldebug_cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mldebug/mldebug_cli.py b/src/mldebug/mldebug_cli.py index d2d5182..eae3ed5 100644 --- a/src/mldebug/mldebug_cli.py +++ b/src/mldebug/mldebug_cli.py @@ -224,7 +224,7 @@ def app(): "--version", action="version", version=version_string(), - help="Show version and the commit this build came from, then exit.\n", + help="Show version, commit ID and exit.\n", ) p.add_argument( "-b",