Last active
June 26, 2023 06:12
-
-
Save tanbro/552bd2584edc032626d1642dbbc831cb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
""" | |
# Report PyProject version | |
The tool print python source code project's version from pip install report with a dry-run. | |
The project MUST have a `pyproject.toml` file with metadata defined in it! | |
- On non-western language Windows, environment `PYTHONUTF8` may be in need . | |
- For Python version smaller than 3.11, package `toml` is required. To install it: | |
pip install "toml;python_version<'3.11'" | |
""" | |
import argparse | |
import json | |
import shlex | |
import subprocess | |
import sys | |
from pathlib import Path | |
from textwrap import dedent | |
if sys.version_info >= (3, 11): | |
import tomllib | |
else: | |
try: | |
import toml as tomllib | |
except ImportError as err: | |
msg = dedent( | |
f""" | |
{err} | |
You can install the library by execute: | |
{sys.executable} -m pip install toml | |
""" | |
).lstrip() | |
print(msg) | |
raise | |
PIP_REPORT_COMMAND_FRAGMENT = [ | |
"pip", | |
"install", | |
"--disable-pip-version-check", | |
"--dry-run", | |
"--no-deps", | |
"--ignore-installed", | |
"--ignore-requires-python", | |
"--quiet", | |
"--report", | |
"-", | |
] | |
def set_args(): | |
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawTextHelpFormatter) | |
parser.add_argument( | |
"--python", | |
"-P", | |
default=f"{sys.executable}", | |
help="Run `pip` module of this Python executable (default: %(default)s).", | |
) | |
help_static_version = ( | |
"Print static version defined in pyproject.toml if possible when the option is true; " | |
"Or always print dynamic version from pip install report. " | |
"(default=%(default)r)" | |
) | |
if sys.version_info >= (3, 9): | |
parser.add_argument( | |
"--static-version", | |
action=argparse.BooleanOptionalAction, | |
default=False, | |
help=help_static_version, | |
) | |
else: | |
parser.add_argument( | |
"--static-version", | |
action="store_true", | |
help=help_static_version, | |
) | |
parser.add_argument( | |
"--pip-options", | |
metavar="OPTIONS", | |
help="Extra options to be supplied to the pip in a string.", | |
) | |
parser.add_argument( | |
"dir", | |
metavar="DIR", | |
nargs="?", | |
default=".", | |
help="Report version of the Python source code project in this directory. A pyproject.toml file MUST be in it. (default=%(default)r)", | |
) | |
return parser.parse_args() | |
def main(args): | |
with Path(args.dir).joinpath("pyproject.toml").open("rb") as fp: | |
pyproject = tomllib.load(fp) | |
project = pyproject["project"] | |
project_name = project["name"] | |
if args.static_version: | |
try: | |
project_version = project["version"] # try find Static version | |
except KeyError: | |
pass | |
else: # Print static version, then exit | |
print(project_version) | |
return | |
# Dynamic version! | |
completed_process = subprocess.run( | |
( | |
[args.python, "-m"] | |
+ PIP_REPORT_COMMAND_FRAGMENT | |
+ (shlex.split(args.pip_options) if args.pip_options else []) | |
+ [args.dir] | |
), | |
capture_output=True, | |
check=True, | |
text=True, | |
) | |
report = json.loads(completed_process.stdout) | |
for package in report["install"]: | |
if package["metadata"]["name"] == project_name: | |
print(package["metadata"]["version"]) | |
break | |
if __name__ == "__main__": | |
exit(main(set_args())) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment