Skip to content

Commit 214371d

Browse files
authored
Dynamically determine the version of the pip package. (#3259)
Use the logic from https://github.com/pytorch/torcharrow/blob/15a7f7124d4c73c8c541547aef072264baab63b7/setup.py#L21 to play nicely with the pytorch ecosystem CI build environment. Test Plan: ``` $ ./install_requirements.sh ... Successfully installed executorch-0.2.0a0+1ba292a $ python >>> from executorch import version >>> version.__version__ '0.2.0a0+1ba292a' >>> version.git_version '1ba292ae4071c4eede8ea14e8f10ffd973a085b4' >>> ^D $ grep Version /home/dbort/.conda/envs/executorch-tmp/lib/python3.10/site-packages/executorch-0.2.0a0+1ba292a.dist-info/METADATA Metadata-Version: 2.1 Version: 0.2.0a0+1ba292a ``` Temporarily commented out the call to `setup()` in `setup.py` then imported it. ``` $ python >>> from setup import Version >>> Version.string '0.2.0a0+1ba292a' >>> Version.git_hash '1ba292ae4071c4eede8ea14e8f10ffd973a085b4' >>> Version.write_to_python_file("/tmp/version.py") >>> ^D $ cat /tmp/version.py from typing import Optional __all__ = ["__version__", "git_version"] __version__ = "0.2.0a0+1ba292a" git_version: Optional[str] = '1ba292ae4071c4eede8ea14e8f10ffd973a085b4' ``` ``` $ BUILD_VERSION="5.5.5" python >>> from setup import Version >>> Version.string '5.5.5' ```
1 parent 3d7a24c commit 214371d

File tree

2 files changed

+80
-4
lines changed

2 files changed

+80
-4
lines changed

pyproject.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ build-backend = "setuptools.build_meta"
1111

1212
[project]
1313
name = "executorch"
14-
# TODO(dbort): Use setuptools-git-versioning or setuptools-scm to get the
15-
# version from the git branch state. For now, use a version that doesn't look
16-
# like a real release.
17-
version = "0.2.0.dev0+unknown"
14+
dynamic = [
15+
# setup.py will set the version.
16+
'version',
17+
]
1818
# Python dependencies required for development
1919
dependencies=[
2020
"expecttest",

setup.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
from distutils import log
5757
from distutils.sysconfig import get_python_lib
5858
from pathlib import Path
59+
from typing import Optional
5960

6061
from setuptools import Extension, setup
6162
from setuptools.command.build import build
@@ -84,6 +85,77 @@ def pybindings(cls) -> bool:
8485
return cls._is_env_enabled("EXECUTORCH_BUILD_PYBIND", default=False)
8586

8687

88+
class Version:
89+
"""Static properties that describe the version of the pip package."""
90+
91+
# Cached values returned by the properties.
92+
__root_dir_attr: Optional[str] = None
93+
__string_attr: Optional[str] = None
94+
__git_hash_attr: Optional[str] = None
95+
96+
@classmethod
97+
@property
98+
def _root_dir(cls) -> str:
99+
"""The path to the root of the git repo."""
100+
if cls.__root_dir_attr is None:
101+
# This setup.py file lives in the root of the repo.
102+
cls.__root_dir_attr = str(Path(__file__).parent.resolve())
103+
return str(cls.__root_dir_attr)
104+
105+
@classmethod
106+
@property
107+
def git_hash(cls) -> Optional[str]:
108+
"""The current git hash, if known."""
109+
if cls.__git_hash_attr is None:
110+
import subprocess
111+
112+
try:
113+
cls.__git_hash_attr = (
114+
subprocess.check_output(
115+
["git", "rev-parse", "HEAD"], cwd=cls._root_dir
116+
)
117+
.decode("ascii")
118+
.strip()
119+
)
120+
except subprocess.CalledProcessError:
121+
cls.__git_hash_attr = "" # Non-None but empty.
122+
# A non-None but empty value indicates that we don't know it.
123+
return cls.__git_hash_attr if cls.__git_hash_attr else None
124+
125+
@classmethod
126+
@property
127+
def string(cls) -> str:
128+
"""The version string."""
129+
if cls.__string_attr is None:
130+
# If set, BUILD_VERSION should override any local version
131+
# information. CI will use this to manage, e.g., release vs. nightly
132+
# versions.
133+
version = os.getenv("BUILD_VERSION", "").strip()
134+
if not version:
135+
# Otherwise, read the version from a local file and add the git
136+
# commit if available.
137+
version = (
138+
open(os.path.join(cls._root_dir, "version.txt")).read().strip()
139+
)
140+
if cls.git_hash:
141+
version += "+" + cls.git_hash[:7]
142+
cls.__string_attr = version
143+
return cls.__string_attr
144+
145+
@classmethod
146+
def write_to_python_file(cls, path: str) -> None:
147+
"""Creates a file similar to PyTorch core's `torch/version.py`."""
148+
lines = [
149+
"from typing import Optional",
150+
'__all__ = ["__version__", "git_version"]',
151+
f'__version__ = "{cls.string}"',
152+
# A string or None.
153+
f"git_version: Optional[str] = {repr(cls.git_hash)}",
154+
]
155+
with open(path, "w") as fp:
156+
fp.write("\n".join(lines) + "\n")
157+
158+
87159
class _BaseExtension(Extension):
88160
"""A base class that maps an abstract source to an abstract destination."""
89161

@@ -269,6 +341,9 @@ def run(self):
269341
# package subdirectory.
270342
dst_root = os.path.join(self.build_lib, self.get_package_dir("executorch"))
271343

344+
# Create the version file.
345+
Version.write_to_python_file(os.path.join(dst_root, "version.py"))
346+
272347
# Manually copy files into the output package directory. These are
273348
# typically python "resource" files that will live alongside the python
274349
# code that uses them.
@@ -447,6 +522,7 @@ def get_ext_modules() -> list[Extension]:
447522

448523

449524
setup(
525+
version=Version.string,
450526
# TODO(dbort): Could use py_modules to restrict the set of modules we
451527
# package, and package_data to restrict the set up non-python files we
452528
# include. See also setuptools/discovery.py for custom finders.

0 commit comments

Comments
 (0)